blob: d0e9bf82bacb50161dcf9f98a63f8e3757ee7eed [file] [log] [blame]
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001// Copyright 2012 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"
danno@chromium.orgfa458e42012-02-01 10:48:36 +000048#include "factory.h"
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
danno@chromium.orgfa458e42012-02-01 10:48:36 +0000557bool Object::IsTypeFeedbackCells() {
558 if (!IsFixedArray()) return false;
559 // There's actually no way to see the difference between a fixed array and
560 // a cache cells array. Since this is used for asserts we can check that
561 // the length is plausible though.
562 if (FixedArray::cast(this)->length() % 2 != 0) return false;
563 return true;
564}
565
566
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000567bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000568 if (Object::IsHeapObject()) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000569 Map* map = HeapObject::cast(this)->map();
570 Heap* heap = map->GetHeap();
571 return (map == heap->function_context_map() ||
572 map == heap->catch_context_map() ||
573 map == heap->with_context_map() ||
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000574 map == heap->global_context_map() ||
575 map == heap->block_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000576 }
577 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000578}
579
580
581bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000582 return Object::IsHeapObject() &&
583 HeapObject::cast(this)->map() ==
584 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000585}
586
587
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000588bool Object::IsScopeInfo() {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000589 return Object::IsHeapObject() &&
590 HeapObject::cast(this)->map() ==
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000591 HeapObject::cast(this)->GetHeap()->scope_info_map();
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000592}
593
594
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000595TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000596
597
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000598template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000599 return obj->IsJSFunction();
600}
601
602
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000603TYPE_CHECKER(Code, CODE_TYPE)
604TYPE_CHECKER(Oddball, ODDBALL_TYPE)
605TYPE_CHECKER(JSGlobalPropertyCell, JS_GLOBAL_PROPERTY_CELL_TYPE)
606TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
607TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000608TYPE_CHECKER(JSDate, JS_DATE_TYPE)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000609TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000610
611
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000612bool Object::IsStringWrapper() {
613 return IsJSValue() && JSValue::cast(this)->value()->IsString();
614}
615
616
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000617TYPE_CHECKER(Foreign, FOREIGN_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000618
619
620bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000621 return IsOddball() &&
622 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000623}
624
625
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000626TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
627TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
ager@chromium.org236ad962008-09-25 09:45:57 +0000628
629
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000630template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000631 return obj->IsJSArray();
632}
633
634
635bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000636 return Object::IsHeapObject() &&
637 HeapObject::cast(this)->map() ==
638 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000639}
640
641
642bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000643 return IsHashTable() &&
644 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000645}
646
647
648bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000649 return IsHashTable() && this ==
650 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000651}
652
653
ager@chromium.orgac091b72010-05-05 07:34:42 +0000654bool Object::IsJSFunctionResultCache() {
655 if (!IsFixedArray()) return false;
656 FixedArray* self = FixedArray::cast(this);
657 int length = self->length();
658 if (length < JSFunctionResultCache::kEntriesIndex) return false;
659 if ((length - JSFunctionResultCache::kEntriesIndex)
660 % JSFunctionResultCache::kEntrySize != 0) {
661 return false;
662 }
663#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000664 if (FLAG_verify_heap) {
665 reinterpret_cast<JSFunctionResultCache*>(this)->
666 JSFunctionResultCacheVerify();
667 }
ager@chromium.orgac091b72010-05-05 07:34:42 +0000668#endif
669 return true;
670}
671
672
ricow@chromium.org65fae842010-08-25 15:26:24 +0000673bool Object::IsNormalizedMapCache() {
674 if (!IsFixedArray()) return false;
675 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
676 return false;
677 }
678#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000679 if (FLAG_verify_heap) {
680 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
681 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000682#endif
683 return true;
684}
685
686
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000687bool Object::IsCompilationCacheTable() {
688 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000689}
690
691
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000692bool Object::IsCodeCacheHashTable() {
693 return IsHashTable();
694}
695
696
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000697bool Object::IsPolymorphicCodeCacheHashTable() {
698 return IsHashTable();
699}
700
701
ager@chromium.org236ad962008-09-25 09:45:57 +0000702bool Object::IsMapCache() {
703 return IsHashTable();
704}
705
706
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000707bool Object::IsPrimitive() {
708 return IsOddball() || IsNumber() || IsString();
709}
710
711
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000712bool Object::IsJSGlobalProxy() {
713 bool result = IsHeapObject() &&
714 (HeapObject::cast(this)->map()->instance_type() ==
715 JS_GLOBAL_PROXY_TYPE);
716 ASSERT(!result || IsAccessCheckNeeded());
717 return result;
718}
719
720
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000721bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000722 if (!IsHeapObject()) return false;
723
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000724 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000725 return type == JS_GLOBAL_OBJECT_TYPE ||
726 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000727}
728
729
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000730TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
731TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000732
733
734bool Object::IsUndetectableObject() {
735 return IsHeapObject()
736 && HeapObject::cast(this)->map()->is_undetectable();
737}
738
739
740bool Object::IsAccessCheckNeeded() {
741 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000742 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000743}
744
745
746bool Object::IsStruct() {
747 if (!IsHeapObject()) return false;
748 switch (HeapObject::cast(this)->map()->instance_type()) {
749#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
750 STRUCT_LIST(MAKE_STRUCT_CASE)
751#undef MAKE_STRUCT_CASE
752 default: return false;
753 }
754}
755
756
757#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
758 bool Object::Is##Name() { \
759 return Object::IsHeapObject() \
760 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
761 }
762 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
763#undef MAKE_STRUCT_PREDICATE
764
765
766bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000767 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000768}
769
770
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000771bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000772 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
773}
774
775
776bool Object::IsTheHole() {
777 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000778}
779
780
781bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000782 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000783}
784
785
786bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000787 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000788}
789
790
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000791bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000792 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000793}
794
795
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000796double Object::Number() {
797 ASSERT(IsNumber());
798 return IsSmi()
799 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
800 : reinterpret_cast<HeapNumber*>(this)->value();
801}
802
803
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +0000804bool Object::IsNaN() {
805 return this->IsHeapNumber() && isnan(HeapNumber::cast(this)->value());
806}
807
808
lrn@chromium.org303ada72010-10-27 09:33:13 +0000809MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000810 if (IsSmi()) return this;
811 if (IsHeapNumber()) {
812 double value = HeapNumber::cast(this)->value();
813 int int_value = FastD2I(value);
814 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
815 return Smi::FromInt(int_value);
816 }
817 }
818 return Failure::Exception();
819}
820
821
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000822bool Object::HasSpecificClassOf(String* name) {
823 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
824}
825
826
lrn@chromium.org303ada72010-10-27 09:33:13 +0000827MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000828 // GetElement can trigger a getter which can cause allocation.
829 // This was not always the case. This ASSERT is here to catch
830 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000831 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000832 return GetElementWithReceiver(this, index);
833}
834
835
lrn@chromium.org303ada72010-10-27 09:33:13 +0000836Object* Object::GetElementNoExceptionThrown(uint32_t index) {
837 MaybeObject* maybe = GetElementWithReceiver(this, index);
838 ASSERT(!maybe->IsFailure());
839 Object* result = NULL; // Initialization to please compiler.
840 maybe->ToObject(&result);
841 return result;
842}
843
844
845MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000846 PropertyAttributes attributes;
847 return GetPropertyWithReceiver(this, key, &attributes);
848}
849
850
lrn@chromium.org303ada72010-10-27 09:33:13 +0000851MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000852 return GetPropertyWithReceiver(this, key, attributes);
853}
854
855
856#define FIELD_ADDR(p, offset) \
857 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
858
859#define READ_FIELD(p, offset) \
860 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
861
862#define WRITE_FIELD(p, offset, value) \
863 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
864
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000865#define WRITE_BARRIER(heap, object, offset, value) \
866 heap->incremental_marking()->RecordWrite( \
867 object, HeapObject::RawField(object, offset), value); \
868 if (heap->InNewSpace(value)) { \
869 heap->RecordWrite(object->address(), offset); \
870 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000871
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000872#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
873 if (mode == UPDATE_WRITE_BARRIER) { \
874 heap->incremental_marking()->RecordWrite( \
875 object, HeapObject::RawField(object, offset), value); \
876 if (heap->InNewSpace(value)) { \
877 heap->RecordWrite(object->address(), offset); \
878 } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000879 }
880
lrn@chromium.org7516f052011-03-30 08:52:27 +0000881#ifndef V8_TARGET_ARCH_MIPS
882 #define READ_DOUBLE_FIELD(p, offset) \
883 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
884#else // V8_TARGET_ARCH_MIPS
885 // Prevent gcc from using load-double (mips ldc1) on (possibly)
886 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000887 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000888 union conversion {
889 double d;
890 uint32_t u[2];
891 } c;
892 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
893 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
894 return c.d;
895 }
896 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
897#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000898
lrn@chromium.org7516f052011-03-30 08:52:27 +0000899#ifndef V8_TARGET_ARCH_MIPS
900 #define WRITE_DOUBLE_FIELD(p, offset, value) \
901 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
902#else // V8_TARGET_ARCH_MIPS
903 // Prevent gcc from using store-double (mips sdc1) on (possibly)
904 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000905 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000906 double value) {
907 union conversion {
908 double d;
909 uint32_t u[2];
910 } c;
911 c.d = value;
912 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
913 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
914 }
915 #define WRITE_DOUBLE_FIELD(p, offset, value) \
916 write_double_field(p, offset, value)
917#endif // V8_TARGET_ARCH_MIPS
918
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000919
920#define READ_INT_FIELD(p, offset) \
921 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
922
923#define WRITE_INT_FIELD(p, offset, value) \
924 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
925
ager@chromium.org3e875802009-06-29 08:26:34 +0000926#define READ_INTPTR_FIELD(p, offset) \
927 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
928
929#define WRITE_INTPTR_FIELD(p, offset, value) \
930 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
931
ager@chromium.org7c537e22008-10-16 08:43:32 +0000932#define READ_UINT32_FIELD(p, offset) \
933 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
934
935#define WRITE_UINT32_FIELD(p, offset, value) \
936 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
937
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000938#define READ_SHORT_FIELD(p, offset) \
939 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
940
941#define WRITE_SHORT_FIELD(p, offset, value) \
942 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
943
944#define READ_BYTE_FIELD(p, offset) \
945 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
946
947#define WRITE_BYTE_FIELD(p, offset, value) \
948 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
949
950
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000951Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
952 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000953}
954
955
956int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000957 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000958}
959
960
961Smi* Smi::FromInt(int value) {
962 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000963 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000964 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000965 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000966 return reinterpret_cast<Smi*>(tagged_value);
967}
968
969
970Smi* Smi::FromIntptr(intptr_t value) {
971 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000972 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
973 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000974}
975
976
977Failure::Type Failure::type() const {
978 return static_cast<Type>(value() & kFailureTypeTagMask);
979}
980
981
982bool Failure::IsInternalError() const {
983 return type() == INTERNAL_ERROR;
984}
985
986
987bool Failure::IsOutOfMemoryException() const {
988 return type() == OUT_OF_MEMORY_EXCEPTION;
989}
990
991
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000992AllocationSpace Failure::allocation_space() const {
993 ASSERT_EQ(RETRY_AFTER_GC, type());
994 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
995 & kSpaceTagMask);
996}
997
998
999Failure* Failure::InternalError() {
1000 return Construct(INTERNAL_ERROR);
1001}
1002
1003
1004Failure* Failure::Exception() {
1005 return Construct(EXCEPTION);
1006}
1007
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001008
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001009Failure* Failure::OutOfMemoryException() {
1010 return Construct(OUT_OF_MEMORY_EXCEPTION);
1011}
1012
1013
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001014intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001015 return static_cast<intptr_t>(
1016 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001017}
1018
1019
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001020Failure* Failure::RetryAfterGC() {
1021 return RetryAfterGC(NEW_SPACE);
1022}
1023
1024
1025Failure* Failure::RetryAfterGC(AllocationSpace space) {
1026 ASSERT((space & ~kSpaceTagMask) == 0);
1027 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001028}
1029
1030
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001031Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001032 uintptr_t info =
1033 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001034 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001035 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001036}
1037
1038
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001039bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001040#ifdef DEBUG
1041 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1042#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001043
1044#ifdef V8_TARGET_ARCH_X64
1045 // To be representable as a long smi, the value must be a 32-bit integer.
1046 bool result = (value == static_cast<int32_t>(value));
1047#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001048 // To be representable as an tagged small integer, the two
1049 // most-significant bits of 'value' must be either 00 or 11 due to
1050 // sign-extension. To check this we add 01 to the two
1051 // most-significant bits, and check if the most-significant bit is 0
1052 //
1053 // CAUTION: The original code below:
1054 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1055 // may lead to incorrect results according to the C language spec, and
1056 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1057 // compiler may produce undefined results in case of signed integer
1058 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001059 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001060#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001061 ASSERT(result == in_range);
1062 return result;
1063}
1064
1065
kasper.lund7276f142008-07-30 08:49:36 +00001066MapWord MapWord::FromMap(Map* map) {
1067 return MapWord(reinterpret_cast<uintptr_t>(map));
1068}
1069
1070
1071Map* MapWord::ToMap() {
1072 return reinterpret_cast<Map*>(value_);
1073}
1074
1075
1076bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001077 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001078}
1079
1080
1081MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001082 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1083 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001084}
1085
1086
1087HeapObject* MapWord::ToForwardingAddress() {
1088 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001089 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001090}
1091
1092
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001093#ifdef DEBUG
1094void HeapObject::VerifyObjectField(int offset) {
1095 VerifyPointer(READ_FIELD(this, offset));
1096}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001097
1098void HeapObject::VerifySmiField(int offset) {
1099 ASSERT(READ_FIELD(this, offset)->IsSmi());
1100}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001101#endif
1102
1103
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001104Heap* HeapObject::GetHeap() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001105 Heap* heap =
1106 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1107 ASSERT(heap != NULL);
1108 ASSERT(heap->isolate() == Isolate::Current());
1109 return heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001110}
1111
1112
1113Isolate* HeapObject::GetIsolate() {
1114 return GetHeap()->isolate();
1115}
1116
1117
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001118Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001119 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001120}
1121
1122
1123void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001124 set_map_word(MapWord::FromMap(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001125 if (value != NULL) {
1126 // TODO(1600) We are passing NULL as a slot because maps can never be on
1127 // evacuation candidate.
1128 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1129 }
1130}
1131
1132
1133// Unsafe accessor omitting write barrier.
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001134void HeapObject::set_map_no_write_barrier(Map* value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001135 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001136}
1137
1138
kasper.lund7276f142008-07-30 08:49:36 +00001139MapWord HeapObject::map_word() {
1140 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1141}
1142
1143
1144void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001145 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001146 // here.
1147 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1148}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001149
1150
1151HeapObject* HeapObject::FromAddress(Address address) {
1152 ASSERT_TAG_ALIGNED(address);
1153 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1154}
1155
1156
1157Address HeapObject::address() {
1158 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1159}
1160
1161
1162int HeapObject::Size() {
1163 return SizeFromMap(map());
1164}
1165
1166
1167void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1168 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1169 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1170}
1171
1172
1173void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1174 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1175}
1176
1177
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001178double HeapNumber::value() {
1179 return READ_DOUBLE_FIELD(this, kValueOffset);
1180}
1181
1182
1183void HeapNumber::set_value(double value) {
1184 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1185}
1186
1187
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001188int HeapNumber::get_exponent() {
1189 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1190 kExponentShift) - kExponentBias;
1191}
1192
1193
1194int HeapNumber::get_sign() {
1195 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1196}
1197
1198
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001199ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001200
1201
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001202Object** FixedArray::GetFirstElementAddress() {
1203 return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1204}
1205
1206
1207bool FixedArray::ContainsOnlySmisOrHoles() {
1208 Object* the_hole = GetHeap()->the_hole_value();
1209 Object** current = GetFirstElementAddress();
1210 for (int i = 0; i < length(); ++i) {
1211 Object* candidate = *current++;
1212 if (!candidate->IsSmi() && candidate != the_hole) return false;
1213 }
1214 return true;
1215}
1216
1217
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001218FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001219 Object* array = READ_FIELD(this, kElementsOffset);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001220 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001221}
1222
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001223void JSObject::ValidateSmiOnlyElements() {
1224#if DEBUG
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001225 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001226 Heap* heap = GetHeap();
1227 // Don't use elements, since integrity checks will fail if there
1228 // are filler pointers in the array.
1229 FixedArray* fixed_array =
1230 reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset));
1231 Map* map = fixed_array->map();
1232 // Arrays that have been shifted in place can't be verified.
1233 if (map != heap->raw_unchecked_one_pointer_filler_map() &&
1234 map != heap->raw_unchecked_two_pointer_filler_map() &&
1235 map != heap->free_space_map()) {
1236 for (int i = 0; i < fixed_array->length(); i++) {
1237 Object* current = fixed_array->get(i);
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001238 ASSERT(current->IsSmi() || current->IsTheHole());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001239 }
1240 }
1241 }
1242#endif
1243}
1244
1245
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001246MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001247#if DEBUG
1248 ValidateSmiOnlyElements();
1249#endif
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001250 if ((map()->elements_kind() != FAST_ELEMENTS)) {
1251 return TransitionElementsKind(FAST_ELEMENTS);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001252 }
1253 return this;
1254}
1255
1256
1257MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001258 uint32_t count,
1259 EnsureElementsMode mode) {
1260 ElementsKind current_kind = map()->elements_kind();
1261 ElementsKind target_kind = current_kind;
1262 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
1263 if (current_kind == FAST_ELEMENTS) return this;
1264
1265 Heap* heap = GetHeap();
1266 Object* the_hole = heap->the_hole_value();
1267 Object* heap_number_map = heap->heap_number_map();
1268 for (uint32_t i = 0; i < count; ++i) {
1269 Object* current = *objects++;
1270 if (!current->IsSmi() && current != the_hole) {
1271 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS &&
1272 HeapObject::cast(current)->map() == heap_number_map) {
1273 target_kind = FAST_DOUBLE_ELEMENTS;
1274 } else {
1275 target_kind = FAST_ELEMENTS;
1276 break;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001277 }
1278 }
1279 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001280
1281 if (target_kind != current_kind) {
1282 return TransitionElementsKind(target_kind);
1283 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001284 return this;
1285}
1286
1287
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001288MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements,
1289 EnsureElementsMode mode) {
1290 if (elements->map() != GetHeap()->fixed_double_array_map()) {
1291 ASSERT(elements->map() == GetHeap()->fixed_array_map() ||
1292 elements->map() == GetHeap()->fixed_cow_array_map());
1293 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1294 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1295 }
1296 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress();
1297 return EnsureCanContainElements(objects, elements->length(), mode);
1298 }
1299
1300 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
1301 if (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) {
1302 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS);
1303 }
1304
1305 return this;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001306}
1307
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001308
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001309MaybeObject* JSObject::GetElementsTransitionMap(Isolate* isolate,
1310 ElementsKind to_kind) {
1311 Map* current_map = map();
1312 ElementsKind from_kind = current_map->elements_kind();
1313
1314 if (from_kind == to_kind) return current_map;
1315
1316 Context* global_context = isolate->context()->global_context();
1317 if (current_map == global_context->smi_js_array_map()) {
1318 if (to_kind == FAST_ELEMENTS) {
1319 return global_context->object_js_array_map();
1320 } else {
1321 if (to_kind == FAST_DOUBLE_ELEMENTS) {
1322 return global_context->double_js_array_map();
1323 } else {
1324 ASSERT(to_kind == DICTIONARY_ELEMENTS);
1325 }
1326 }
1327 }
1328 return GetElementsTransitionMapSlow(to_kind);
1329}
1330
1331
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001332void JSObject::set_map_and_elements(Map* new_map,
1333 FixedArrayBase* value,
1334 WriteBarrierMode mode) {
1335 ASSERT(value->HasValidElements());
1336#ifdef DEBUG
1337 ValidateSmiOnlyElements();
1338#endif
1339 if (new_map != NULL) {
1340 if (mode == UPDATE_WRITE_BARRIER) {
1341 set_map(new_map);
1342 } else {
1343 ASSERT(mode == SKIP_WRITE_BARRIER);
1344 set_map_no_write_barrier(new_map);
1345 }
1346 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001347 ASSERT((map()->has_fast_elements() ||
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001348 map()->has_fast_smi_only_elements() ||
1349 (value == GetHeap()->empty_fixed_array())) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001350 (value->map() == GetHeap()->fixed_array_map() ||
1351 value->map() == GetHeap()->fixed_cow_array_map()));
ulan@chromium.org65a89c22012-02-14 11:46:07 +00001352 ASSERT((value == GetHeap()->empty_fixed_array()) ||
1353 (map()->has_fast_double_elements() == value->IsFixedDoubleArray()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001354 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001355 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001356}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001357
1358
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001359void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1360 set_map_and_elements(NULL, value, mode);
1361}
1362
1363
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001364void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001365 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1366 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001367}
1368
1369
1370void JSObject::initialize_elements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001371 ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001372 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1373 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001374}
1375
1376
lrn@chromium.org303ada72010-10-27 09:33:13 +00001377MaybeObject* JSObject::ResetElements() {
1378 Object* obj;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001379 ElementsKind elements_kind = FLAG_smi_only_arrays
1380 ? FAST_SMI_ONLY_ELEMENTS
1381 : FAST_ELEMENTS;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00001382 MaybeObject* maybe_obj = GetElementsTransitionMap(GetIsolate(),
1383 elements_kind);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001384 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001385 set_map(Map::cast(obj));
1386 initialize_elements();
1387 return this;
1388}
1389
1390
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001391ACCESSORS(Oddball, to_string, String, kToStringOffset)
1392ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1393
1394
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001395byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001396 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001397}
1398
1399
1400void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001401 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001402}
1403
1404
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001405Object* JSGlobalPropertyCell::value() {
1406 return READ_FIELD(this, kValueOffset);
1407}
1408
1409
1410void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1411 // The write barrier is not used for global property cells.
1412 ASSERT(!val->IsJSGlobalPropertyCell());
1413 WRITE_FIELD(this, kValueOffset, val);
1414}
1415
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001416
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001417int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001418 InstanceType type = map()->instance_type();
1419 // Check for the most common kind of JavaScript object before
1420 // falling into the generic switch. This speeds up the internal
1421 // field operations considerably on average.
1422 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1423 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001424 case JS_GLOBAL_PROXY_TYPE:
1425 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001426 case JS_GLOBAL_OBJECT_TYPE:
1427 return JSGlobalObject::kSize;
1428 case JS_BUILTINS_OBJECT_TYPE:
1429 return JSBuiltinsObject::kSize;
1430 case JS_FUNCTION_TYPE:
1431 return JSFunction::kSize;
1432 case JS_VALUE_TYPE:
1433 return JSValue::kSize;
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00001434 case JS_DATE_TYPE:
1435 return JSDate::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001436 case JS_ARRAY_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001437 return JSArray::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001438 case JS_WEAK_MAP_TYPE:
1439 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001440 case JS_REGEXP_TYPE:
ulan@chromium.org2efb9002012-01-19 15:36:35 +00001441 return JSRegExp::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001442 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001443 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001444 case JS_MESSAGE_OBJECT_TYPE:
1445 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001446 default:
1447 UNREACHABLE();
1448 return 0;
1449 }
1450}
1451
1452
1453int JSObject::GetInternalFieldCount() {
1454 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001455 // Make sure to adjust for the number of in-object properties. These
1456 // properties do contribute to the size, but are not internal fields.
1457 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1458 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001459}
1460
1461
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001462int JSObject::GetInternalFieldOffset(int index) {
1463 ASSERT(index < GetInternalFieldCount() && index >= 0);
1464 return GetHeaderSize() + (kPointerSize * index);
1465}
1466
1467
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001468Object* JSObject::GetInternalField(int index) {
1469 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001470 // Internal objects do follow immediately after the header, whereas in-object
1471 // properties are at the end of the object. Therefore there is no need
1472 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001473 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1474}
1475
1476
1477void JSObject::SetInternalField(int index, Object* value) {
1478 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001479 // Internal objects do follow immediately after the header, whereas in-object
1480 // properties are at the end of the object. Therefore there is no need
1481 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001482 int offset = GetHeaderSize() + (kPointerSize * index);
1483 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001484 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001485}
1486
1487
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001488void JSObject::SetInternalField(int index, Smi* value) {
1489 ASSERT(index < GetInternalFieldCount() && index >= 0);
1490 // Internal objects do follow immediately after the header, whereas in-object
1491 // properties are at the end of the object. Therefore there is no need
1492 // to adjust the index here.
1493 int offset = GetHeaderSize() + (kPointerSize * index);
1494 WRITE_FIELD(this, offset, value);
1495}
1496
1497
ager@chromium.org7c537e22008-10-16 08:43:32 +00001498// Access fast-case object properties at index. The use of these routines
1499// is needed to correctly distinguish between properties stored in-object and
1500// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001501Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001502 // Adjust for the number of properties stored in the object.
1503 index -= map()->inobject_properties();
1504 if (index < 0) {
1505 int offset = map()->instance_size() + (index * kPointerSize);
1506 return READ_FIELD(this, offset);
1507 } else {
1508 ASSERT(index < properties()->length());
1509 return properties()->get(index);
1510 }
1511}
1512
1513
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001514Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001515 // Adjust for the number of properties stored in the object.
1516 index -= map()->inobject_properties();
1517 if (index < 0) {
1518 int offset = map()->instance_size() + (index * kPointerSize);
1519 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001520 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001521 } else {
1522 ASSERT(index < properties()->length());
1523 properties()->set(index, value);
1524 }
1525 return value;
1526}
1527
1528
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001529int JSObject::GetInObjectPropertyOffset(int index) {
1530 // Adjust for the number of properties stored in the object.
1531 index -= map()->inobject_properties();
1532 ASSERT(index < 0);
1533 return map()->instance_size() + (index * kPointerSize);
1534}
1535
1536
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001537Object* JSObject::InObjectPropertyAt(int index) {
1538 // Adjust for the number of properties stored in the object.
1539 index -= map()->inobject_properties();
1540 ASSERT(index < 0);
1541 int offset = map()->instance_size() + (index * kPointerSize);
1542 return READ_FIELD(this, offset);
1543}
1544
1545
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001546Object* JSObject::InObjectPropertyAtPut(int index,
1547 Object* value,
1548 WriteBarrierMode mode) {
1549 // Adjust for the number of properties stored in the object.
1550 index -= map()->inobject_properties();
1551 ASSERT(index < 0);
1552 int offset = map()->instance_size() + (index * kPointerSize);
1553 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001554 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001555 return value;
1556}
1557
1558
1559
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001560void JSObject::InitializeBody(Map* map,
1561 Object* pre_allocated_value,
1562 Object* filler_value) {
1563 ASSERT(!filler_value->IsHeapObject() ||
1564 !GetHeap()->InNewSpace(filler_value));
1565 ASSERT(!pre_allocated_value->IsHeapObject() ||
1566 !GetHeap()->InNewSpace(pre_allocated_value));
1567 int size = map->instance_size();
1568 int offset = kHeaderSize;
1569 if (filler_value != pre_allocated_value) {
1570 int pre_allocated = map->pre_allocated_property_fields();
1571 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1572 for (int i = 0; i < pre_allocated; i++) {
1573 WRITE_FIELD(this, offset, pre_allocated_value);
1574 offset += kPointerSize;
1575 }
1576 }
1577 while (offset < size) {
1578 WRITE_FIELD(this, offset, filler_value);
1579 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001580 }
1581}
1582
1583
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001584bool JSObject::HasFastProperties() {
1585 return !properties()->IsDictionary();
1586}
1587
1588
1589int JSObject::MaxFastProperties() {
1590 // Allow extra fast properties if the object has more than
1591 // kMaxFastProperties in-object properties. When this is the case,
1592 // it is very unlikely that the object is being used as a dictionary
1593 // and there is a good chance that allowing more map transitions
1594 // will be worth it.
1595 return Max(map()->inobject_properties(), kMaxFastProperties);
1596}
1597
1598
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001599void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001600 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001601 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001602 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001603 }
1604}
1605
1606
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001607bool Object::ToArrayIndex(uint32_t* index) {
1608 if (IsSmi()) {
1609 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001610 if (value < 0) return false;
1611 *index = value;
1612 return true;
1613 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001614 if (IsHeapNumber()) {
1615 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001616 uint32_t uint_value = static_cast<uint32_t>(value);
1617 if (value == static_cast<double>(uint_value)) {
1618 *index = uint_value;
1619 return true;
1620 }
1621 }
1622 return false;
1623}
1624
1625
1626bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1627 if (!this->IsJSValue()) return false;
1628
1629 JSValue* js_value = JSValue::cast(this);
1630 if (!js_value->value()->IsString()) return false;
1631
1632 String* str = String::cast(js_value->value());
1633 if (index >= (uint32_t)str->length()) return false;
1634
1635 return true;
1636}
1637
1638
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001639FixedArrayBase* FixedArrayBase::cast(Object* object) {
1640 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1641 return reinterpret_cast<FixedArrayBase*>(object);
1642}
1643
1644
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001645Object* FixedArray::get(int index) {
1646 ASSERT(index >= 0 && index < this->length());
1647 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1648}
1649
1650
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001651void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001652 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001653 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001654 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1655 int offset = kHeaderSize + index * kPointerSize;
1656 WRITE_FIELD(this, offset, value);
1657}
1658
1659
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001660void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001661 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001662 ASSERT(index >= 0 && index < this->length());
1663 int offset = kHeaderSize + index * kPointerSize;
1664 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001665 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001666}
1667
1668
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001669inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1670 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1671}
1672
1673
1674inline double FixedDoubleArray::hole_nan_as_double() {
1675 return BitCast<double, uint64_t>(kHoleNanInt64);
1676}
1677
1678
1679inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1680 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1681 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1682 return OS::nan_value();
1683}
1684
1685
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001686double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001687 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1688 map() != HEAP->fixed_array_map());
1689 ASSERT(index >= 0 && index < this->length());
1690 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1691 ASSERT(!is_the_hole_nan(result));
1692 return result;
1693}
1694
1695
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001696MaybeObject* FixedDoubleArray::get(int index) {
1697 if (is_the_hole(index)) {
1698 return GetHeap()->the_hole_value();
1699 } else {
1700 return GetHeap()->NumberFromDouble(get_scalar(index));
1701 }
1702}
1703
1704
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001705void FixedDoubleArray::set(int index, double value) {
1706 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1707 map() != HEAP->fixed_array_map());
1708 int offset = kHeaderSize + index * kDoubleSize;
1709 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1710 WRITE_DOUBLE_FIELD(this, offset, value);
1711}
1712
1713
1714void FixedDoubleArray::set_the_hole(int index) {
1715 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1716 map() != HEAP->fixed_array_map());
1717 int offset = kHeaderSize + index * kDoubleSize;
1718 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1719}
1720
1721
1722bool FixedDoubleArray::is_the_hole(int index) {
1723 int offset = kHeaderSize + index * kDoubleSize;
1724 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1725}
1726
1727
1728void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1729 int old_length = from->length();
1730 ASSERT(old_length < length());
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001731 if (old_length * kDoubleSize >= OS::kMinComplexMemCopy) {
1732 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1733 FIELD_ADDR(from, kHeaderSize),
1734 old_length * kDoubleSize);
1735 } else {
1736 for (int i = 0; i < old_length; ++i) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001737 if (from->is_the_hole(i)) {
1738 set_the_hole(i);
1739 } else {
1740 set(i, from->get_scalar(i));
1741 }
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001742 }
1743 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001744 int offset = kHeaderSize + old_length * kDoubleSize;
1745 for (int current = from->length(); current < length(); ++current) {
1746 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1747 offset += kDoubleSize;
1748 }
1749}
1750
1751
1752void FixedDoubleArray::Initialize(FixedArray* from) {
1753 int old_length = from->length();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001754 ASSERT(old_length <= length());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001755 for (int i = 0; i < old_length; i++) {
1756 Object* hole_or_object = from->get(i);
1757 if (hole_or_object->IsTheHole()) {
1758 set_the_hole(i);
1759 } else {
1760 set(i, hole_or_object->Number());
1761 }
1762 }
1763 int offset = kHeaderSize + old_length * kDoubleSize;
1764 for (int current = from->length(); current < length(); ++current) {
1765 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1766 offset += kDoubleSize;
1767 }
1768}
1769
1770
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00001771void FixedDoubleArray::Initialize(SeededNumberDictionary* from) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001772 int offset = kHeaderSize;
1773 for (int current = 0; current < length(); ++current) {
1774 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1775 offset += kDoubleSize;
1776 }
1777 for (int i = 0; i < from->Capacity(); i++) {
1778 Object* key = from->KeyAt(i);
1779 if (key->IsNumber()) {
1780 uint32_t entry = static_cast<uint32_t>(key->Number());
1781 set(entry, from->ValueAt(i)->Number());
1782 }
1783 }
1784}
1785
1786
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001787WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001788 Heap* heap = GetHeap();
1789 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1790 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001791 return UPDATE_WRITE_BARRIER;
1792}
1793
1794
1795void FixedArray::set(int index,
1796 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001797 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001798 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001799 ASSERT(index >= 0 && index < this->length());
1800 int offset = kHeaderSize + index * kPointerSize;
1801 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001802 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001803}
1804
1805
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001806void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
1807 int index,
1808 Object* value) {
1809 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
1810 ASSERT(index >= 0 && index < array->length());
1811 int offset = kHeaderSize + index * kPointerSize;
1812 WRITE_FIELD(array, offset, value);
1813 Heap* heap = array->GetHeap();
1814 if (heap->InNewSpace(value)) {
1815 heap->RecordWrite(array->address(), offset);
1816 }
1817}
1818
1819
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001820void FixedArray::NoWriteBarrierSet(FixedArray* array,
1821 int index,
1822 Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001823 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001824 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001825 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001826 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1827}
1828
1829
1830void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001831 ASSERT(map() != HEAP->fixed_cow_array_map());
1832 set_undefined(GetHeap(), index);
1833}
1834
1835
1836void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001837 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001838 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001839 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001840 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001841}
1842
1843
ager@chromium.org236ad962008-09-25 09:45:57 +00001844void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001845 set_null(GetHeap(), index);
1846}
1847
1848
1849void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001850 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001851 ASSERT(!heap->InNewSpace(heap->null_value()));
1852 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001853}
1854
1855
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001856void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001857 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001858 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001859 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1860 WRITE_FIELD(this,
1861 kHeaderSize + index * kPointerSize,
1862 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001863}
1864
1865
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001866void FixedArray::set_unchecked(int index, Smi* value) {
1867 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1868 int offset = kHeaderSize + index * kPointerSize;
1869 WRITE_FIELD(this, offset, value);
1870}
1871
1872
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001873void FixedArray::set_unchecked(Heap* heap,
1874 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001875 Object* value,
1876 WriteBarrierMode mode) {
1877 int offset = kHeaderSize + index * kPointerSize;
1878 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001879 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001880}
1881
1882
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001883void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001884 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001885 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1886 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001887}
1888
1889
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001890Object** FixedArray::data_start() {
1891 return HeapObject::RawField(this, kHeaderSize);
1892}
1893
1894
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001895bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001896 ASSERT(this->IsSmi() ||
1897 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001898 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001899 return this->IsSmi() || length() <= kFirstIndex;
1900}
1901
1902
1903int DescriptorArray::bit_field3_storage() {
1904 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1905 return Smi::cast(storage)->value();
1906}
1907
1908void DescriptorArray::set_bit_field3_storage(int value) {
1909 ASSERT(!IsEmpty());
1910 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001911}
1912
1913
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001914void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array,
1915 int first,
1916 int second) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001917 Object* tmp = array->get(first);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001918 NoIncrementalWriteBarrierSet(array, first, array->get(second));
1919 NoIncrementalWriteBarrierSet(array, second, tmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001920}
1921
1922
1923int DescriptorArray::Search(String* name) {
1924 SLOW_ASSERT(IsSortedNoDuplicates());
1925
1926 // Check for empty descriptor array.
1927 int nof = number_of_descriptors();
1928 if (nof == 0) return kNotFound;
1929
1930 // Fast case: do linear search for small arrays.
1931 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001932 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001933 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001934 }
1935
1936 // Slow case: perform binary search.
1937 return BinarySearch(name, 0, nof - 1);
1938}
1939
1940
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001941int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001942 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001943 if (number == DescriptorLookupCache::kAbsent) {
1944 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001945 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001946 }
1947 return number;
1948}
1949
1950
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001951String* DescriptorArray::GetKey(int descriptor_number) {
1952 ASSERT(descriptor_number < number_of_descriptors());
1953 return String::cast(get(ToKeyIndex(descriptor_number)));
1954}
1955
1956
1957Object* DescriptorArray::GetValue(int descriptor_number) {
1958 ASSERT(descriptor_number < number_of_descriptors());
1959 return GetContentArray()->get(ToValueIndex(descriptor_number));
1960}
1961
1962
1963Smi* DescriptorArray::GetDetails(int descriptor_number) {
1964 ASSERT(descriptor_number < number_of_descriptors());
1965 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1966}
1967
1968
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001969PropertyType DescriptorArray::GetType(int descriptor_number) {
1970 ASSERT(descriptor_number < number_of_descriptors());
1971 return PropertyDetails(GetDetails(descriptor_number)).type();
1972}
1973
1974
1975int DescriptorArray::GetFieldIndex(int descriptor_number) {
1976 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1977}
1978
1979
1980JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1981 return JSFunction::cast(GetValue(descriptor_number));
1982}
1983
1984
1985Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1986 ASSERT(GetType(descriptor_number) == CALLBACKS);
1987 return GetValue(descriptor_number);
1988}
1989
1990
1991AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1992 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001993 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001994 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001995}
1996
1997
1998bool DescriptorArray::IsProperty(int descriptor_number) {
ulan@chromium.org9a21ec42012-03-06 08:42:24 +00001999 Entry entry(this, descriptor_number);
2000 return IsPropertyDescriptor(&entry);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002001}
2002
2003
rossberg@chromium.org994edf62012-02-06 10:12:55 +00002004bool DescriptorArray::IsTransitionOnly(int descriptor_number) {
2005 switch (GetType(descriptor_number)) {
2006 case MAP_TRANSITION:
2007 case CONSTANT_TRANSITION:
2008 case ELEMENTS_TRANSITION:
2009 return true;
2010 case CALLBACKS: {
2011 Object* value = GetValue(descriptor_number);
2012 if (!value->IsAccessorPair()) return false;
2013 AccessorPair* accessors = AccessorPair::cast(value);
2014 return accessors->getter()->IsMap() && accessors->setter()->IsMap();
2015 }
2016 case NORMAL:
2017 case FIELD:
2018 case CONSTANT_FUNCTION:
2019 case HANDLER:
2020 case INTERCEPTOR:
2021 case NULL_DESCRIPTOR:
2022 return false;
2023 }
2024 UNREACHABLE(); // Keep the compiler happy.
2025 return false;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002026}
2027
2028
2029bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
2030 return GetType(descriptor_number) == NULL_DESCRIPTOR;
2031}
2032
2033
2034bool DescriptorArray::IsDontEnum(int descriptor_number) {
2035 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
2036}
2037
2038
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002039void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2040 desc->Init(GetKey(descriptor_number),
2041 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002042 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002043}
2044
2045
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002046void DescriptorArray::Set(int descriptor_number,
2047 Descriptor* desc,
2048 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002049 // Range check.
2050 ASSERT(descriptor_number < number_of_descriptors());
2051
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002052 NoIncrementalWriteBarrierSet(this,
2053 ToKeyIndex(descriptor_number),
2054 desc->GetKey());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002055 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002056 NoIncrementalWriteBarrierSet(content_array,
2057 ToValueIndex(descriptor_number),
2058 desc->GetValue());
2059 NoIncrementalWriteBarrierSet(content_array,
2060 ToDetailsIndex(descriptor_number),
2061 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002062}
2063
2064
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002065void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
2066 int first, int second) {
2067 NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002068 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002069 NoIncrementalWriteBarrierSwap(content_array,
2070 ToValueIndex(first),
2071 ToValueIndex(second));
2072 NoIncrementalWriteBarrierSwap(content_array,
2073 ToDetailsIndex(first),
2074 ToDetailsIndex(second));
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002075}
2076
2077
2078DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
2079 : marking_(array->GetHeap()->incremental_marking()) {
2080 marking_->EnterNoMarkingScope();
2081 if (array->number_of_descriptors() > 0) {
2082 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
2083 ASSERT(Marking::Color(array->GetContentArray()) == Marking::WHITE_OBJECT);
2084 }
2085}
2086
2087
2088DescriptorArray::WhitenessWitness::~WhitenessWitness() {
2089 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002090}
2091
2092
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002093template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002094int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2095 const int kMinCapacity = 32;
2096 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2097 if (capacity < kMinCapacity) {
2098 capacity = kMinCapacity; // Guarantee min capacity.
2099 }
2100 return capacity;
2101}
2102
2103
2104template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002105int HashTable<Shape, Key>::FindEntry(Key key) {
2106 return FindEntry(GetIsolate(), key);
2107}
2108
2109
2110// Find entry for key otherwise return kNotFound.
2111template<typename Shape, typename Key>
2112int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2113 uint32_t capacity = Capacity();
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002114 uint32_t entry = FirstProbe(HashTable<Shape, Key>::Hash(key), capacity);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002115 uint32_t count = 1;
2116 // EnsureCapacity will guarantee the hash table is never full.
2117 while (true) {
2118 Object* element = KeyAt(entry);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002119 // Empty entry.
2120 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2121 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002122 Shape::IsMatch(key, element)) return entry;
2123 entry = NextProbe(entry, count++, capacity);
2124 }
2125 return kNotFound;
2126}
2127
2128
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002129bool SeededNumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002130 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002131 if (!max_index_object->IsSmi()) return false;
2132 return 0 !=
2133 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2134}
2135
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002136uint32_t SeededNumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002137 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002138 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002139 if (!max_index_object->IsSmi()) return 0;
2140 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2141 return value >> kRequiresSlowElementsTagSize;
2142}
2143
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00002144void SeededNumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002145 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002146}
2147
2148
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002149// ------------------------------------
2150// Cast operations
2151
2152
2153CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002154CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002155CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002156CAST_ACCESSOR(DeoptimizationInputData)
2157CAST_ACCESSOR(DeoptimizationOutputData)
danno@chromium.orgfa458e42012-02-01 10:48:36 +00002158CAST_ACCESSOR(TypeFeedbackCells)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002159CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002160CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002161CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002162CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002163CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002164CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002165CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002166CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002167CAST_ACCESSOR(String)
2168CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002169CAST_ACCESSOR(SeqAsciiString)
2170CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002171CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002172CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002173CAST_ACCESSOR(ExternalString)
2174CAST_ACCESSOR(ExternalAsciiString)
2175CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002176CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002177CAST_ACCESSOR(JSObject)
2178CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002179CAST_ACCESSOR(HeapObject)
2180CAST_ACCESSOR(HeapNumber)
2181CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002182CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002183CAST_ACCESSOR(SharedFunctionInfo)
2184CAST_ACCESSOR(Map)
2185CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002186CAST_ACCESSOR(GlobalObject)
2187CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002188CAST_ACCESSOR(JSGlobalObject)
2189CAST_ACCESSOR(JSBuiltinsObject)
2190CAST_ACCESSOR(Code)
2191CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002192CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002193CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002194CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002195CAST_ACCESSOR(JSSet)
2196CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002197CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002198CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002199CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002200CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002201CAST_ACCESSOR(ExternalArray)
2202CAST_ACCESSOR(ExternalByteArray)
2203CAST_ACCESSOR(ExternalUnsignedByteArray)
2204CAST_ACCESSOR(ExternalShortArray)
2205CAST_ACCESSOR(ExternalUnsignedShortArray)
2206CAST_ACCESSOR(ExternalIntArray)
2207CAST_ACCESSOR(ExternalUnsignedIntArray)
2208CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002209CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002210CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002211CAST_ACCESSOR(Struct)
2212
2213
2214#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2215 STRUCT_LIST(MAKE_STRUCT_CAST)
2216#undef MAKE_STRUCT_CAST
2217
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002218
2219template <typename Shape, typename Key>
2220HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002221 ASSERT(obj->IsHashTable());
2222 return reinterpret_cast<HashTable*>(obj);
2223}
2224
2225
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002226SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002227SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002228
ager@chromium.orgac091b72010-05-05 07:34:42 +00002229SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002230
2231
2232uint32_t String::hash_field() {
2233 return READ_UINT32_FIELD(this, kHashFieldOffset);
2234}
2235
2236
2237void String::set_hash_field(uint32_t value) {
2238 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002239#if V8_HOST_ARCH_64_BIT
2240 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2241#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002242}
2243
2244
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002245bool String::Equals(String* other) {
2246 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002247 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2248 return false;
2249 }
2250 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002251}
2252
2253
lrn@chromium.org303ada72010-10-27 09:33:13 +00002254MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002255 if (!StringShape(this).IsCons()) return this;
2256 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002257 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002258 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002259}
2260
2261
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002262String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002263 MaybeObject* flat = TryFlatten(pretenure);
2264 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002265 if (!flat->ToObject(&successfully_flattened)) return this;
2266 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002267}
2268
2269
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002270uint16_t String::Get(int index) {
2271 ASSERT(index >= 0 && index < length());
2272 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002273 case kSeqStringTag | kAsciiStringTag:
2274 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2275 case kSeqStringTag | kTwoByteStringTag:
2276 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2277 case kConsStringTag | kAsciiStringTag:
2278 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002279 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002280 case kExternalStringTag | kAsciiStringTag:
2281 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2282 case kExternalStringTag | kTwoByteStringTag:
2283 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002284 case kSlicedStringTag | kAsciiStringTag:
2285 case kSlicedStringTag | kTwoByteStringTag:
2286 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002287 default:
2288 break;
2289 }
2290
2291 UNREACHABLE();
2292 return 0;
2293}
2294
2295
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002296void String::Set(int index, uint16_t value) {
2297 ASSERT(index >= 0 && index < length());
2298 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002299
ager@chromium.org5ec48922009-05-05 07:25:34 +00002300 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002301 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2302 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002303}
2304
2305
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002306bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002307 if (!StringShape(this).IsCons()) return true;
2308 return ConsString::cast(this)->second()->length() == 0;
2309}
2310
2311
2312String* String::GetUnderlying() {
2313 // Giving direct access to underlying string only makes sense if the
2314 // wrapping string is already flattened.
2315 ASSERT(this->IsFlat());
2316 ASSERT(StringShape(this).IsIndirect());
2317 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2318 const int kUnderlyingOffset = SlicedString::kParentOffset;
2319 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002320}
2321
2322
ager@chromium.org7c537e22008-10-16 08:43:32 +00002323uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002324 ASSERT(index >= 0 && index < length());
2325 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2326}
2327
2328
ager@chromium.org7c537e22008-10-16 08:43:32 +00002329void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002330 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2331 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2332 static_cast<byte>(value));
2333}
2334
2335
ager@chromium.org7c537e22008-10-16 08:43:32 +00002336Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002337 return FIELD_ADDR(this, kHeaderSize);
2338}
2339
2340
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002341char* SeqAsciiString::GetChars() {
2342 return reinterpret_cast<char*>(GetCharsAddress());
2343}
2344
2345
ager@chromium.org7c537e22008-10-16 08:43:32 +00002346Address SeqTwoByteString::GetCharsAddress() {
2347 return FIELD_ADDR(this, kHeaderSize);
2348}
2349
2350
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002351uc16* SeqTwoByteString::GetChars() {
2352 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2353}
2354
2355
ager@chromium.org7c537e22008-10-16 08:43:32 +00002356uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002357 ASSERT(index >= 0 && index < length());
2358 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2359}
2360
2361
ager@chromium.org7c537e22008-10-16 08:43:32 +00002362void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002363 ASSERT(index >= 0 && index < length());
2364 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2365}
2366
2367
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002368int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002369 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002370}
2371
2372
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002373int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002374 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002375}
2376
2377
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002378String* SlicedString::parent() {
2379 return String::cast(READ_FIELD(this, kParentOffset));
2380}
2381
2382
2383void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002384 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002385 WRITE_FIELD(this, kParentOffset, parent);
2386}
2387
2388
2389SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2390
2391
ager@chromium.org870a0b62008-11-04 11:43:05 +00002392String* ConsString::first() {
2393 return String::cast(READ_FIELD(this, kFirstOffset));
2394}
2395
2396
2397Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002398 return READ_FIELD(this, kFirstOffset);
2399}
2400
2401
ager@chromium.org870a0b62008-11-04 11:43:05 +00002402void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002403 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002404 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002405}
2406
2407
ager@chromium.org870a0b62008-11-04 11:43:05 +00002408String* ConsString::second() {
2409 return String::cast(READ_FIELD(this, kSecondOffset));
2410}
2411
2412
2413Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002414 return READ_FIELD(this, kSecondOffset);
2415}
2416
2417
ager@chromium.org870a0b62008-11-04 11:43:05 +00002418void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002419 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002420 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002421}
2422
2423
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002424bool ExternalString::is_short() {
2425 InstanceType type = map()->instance_type();
2426 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002427}
2428
2429
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002430const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002431 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2432}
2433
2434
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002435void ExternalAsciiString::update_data_cache() {
2436 if (is_short()) return;
2437 const char** data_field =
2438 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2439 *data_field = resource()->data();
2440}
2441
2442
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002443void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002444 const ExternalAsciiString::Resource* resource) {
2445 *reinterpret_cast<const Resource**>(
2446 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002447 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002448}
2449
2450
2451const char* ExternalAsciiString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002452 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002453}
2454
2455
2456uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2457 ASSERT(index >= 0 && index < length());
2458 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002459}
2460
2461
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002462const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002463 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2464}
2465
2466
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002467void ExternalTwoByteString::update_data_cache() {
2468 if (is_short()) return;
2469 const uint16_t** data_field =
2470 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2471 *data_field = resource()->data();
2472}
2473
2474
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002475void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002476 const ExternalTwoByteString::Resource* resource) {
2477 *reinterpret_cast<const Resource**>(
2478 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002479 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002480}
2481
2482
2483const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002484 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002485}
2486
2487
2488uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2489 ASSERT(index >= 0 && index < length());
2490 return GetChars()[index];
2491}
2492
2493
2494const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2495 unsigned start) {
2496 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002497}
2498
2499
ager@chromium.orgac091b72010-05-05 07:34:42 +00002500void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002501 set_finger_index(kEntriesIndex);
2502 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002503}
2504
2505
2506void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002507 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002508 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002509 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002510 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002511 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002512 MakeZeroSize();
2513}
2514
2515
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002516int JSFunctionResultCache::size() {
2517 return Smi::cast(get(kCacheSizeIndex))->value();
2518}
2519
2520
2521void JSFunctionResultCache::set_size(int size) {
2522 set(kCacheSizeIndex, Smi::FromInt(size));
2523}
2524
2525
2526int JSFunctionResultCache::finger_index() {
2527 return Smi::cast(get(kFingerIndex))->value();
2528}
2529
2530
2531void JSFunctionResultCache::set_finger_index(int finger_index) {
2532 set(kFingerIndex, Smi::FromInt(finger_index));
2533}
2534
2535
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002536byte ByteArray::get(int index) {
2537 ASSERT(index >= 0 && index < this->length());
2538 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2539}
2540
2541
2542void ByteArray::set(int index, byte value) {
2543 ASSERT(index >= 0 && index < this->length());
2544 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2545}
2546
2547
2548int ByteArray::get_int(int index) {
2549 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2550 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2551}
2552
2553
2554ByteArray* ByteArray::FromDataStartAddress(Address address) {
2555 ASSERT_TAG_ALIGNED(address);
2556 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2557}
2558
2559
2560Address ByteArray::GetDataStartAddress() {
2561 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2562}
2563
2564
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002565uint8_t* ExternalPixelArray::external_pixel_pointer() {
2566 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002567}
2568
2569
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002570uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002571 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002572 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002573 return ptr[index];
2574}
2575
2576
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002577MaybeObject* ExternalPixelArray::get(int index) {
2578 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2579}
2580
2581
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002582void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002583 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002584 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002585 ptr[index] = value;
2586}
2587
2588
ager@chromium.org3811b432009-10-28 14:53:37 +00002589void* ExternalArray::external_pointer() {
2590 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2591 return reinterpret_cast<void*>(ptr);
2592}
2593
2594
2595void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2596 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2597 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2598}
2599
2600
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002601int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002602 ASSERT((index >= 0) && (index < this->length()));
2603 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2604 return ptr[index];
2605}
2606
2607
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002608MaybeObject* ExternalByteArray::get(int index) {
2609 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2610}
2611
2612
ager@chromium.org3811b432009-10-28 14:53:37 +00002613void ExternalByteArray::set(int index, int8_t value) {
2614 ASSERT((index >= 0) && (index < this->length()));
2615 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2616 ptr[index] = value;
2617}
2618
2619
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002620uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002621 ASSERT((index >= 0) && (index < this->length()));
2622 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2623 return ptr[index];
2624}
2625
2626
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002627MaybeObject* ExternalUnsignedByteArray::get(int index) {
2628 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2629}
2630
2631
ager@chromium.org3811b432009-10-28 14:53:37 +00002632void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2633 ASSERT((index >= 0) && (index < this->length()));
2634 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2635 ptr[index] = value;
2636}
2637
2638
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002639int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002640 ASSERT((index >= 0) && (index < this->length()));
2641 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2642 return ptr[index];
2643}
2644
2645
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002646MaybeObject* ExternalShortArray::get(int index) {
2647 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2648}
2649
2650
ager@chromium.org3811b432009-10-28 14:53:37 +00002651void ExternalShortArray::set(int index, int16_t value) {
2652 ASSERT((index >= 0) && (index < this->length()));
2653 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2654 ptr[index] = value;
2655}
2656
2657
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002658uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002659 ASSERT((index >= 0) && (index < this->length()));
2660 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2661 return ptr[index];
2662}
2663
2664
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002665MaybeObject* ExternalUnsignedShortArray::get(int index) {
2666 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2667}
2668
2669
ager@chromium.org3811b432009-10-28 14:53:37 +00002670void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2671 ASSERT((index >= 0) && (index < this->length()));
2672 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2673 ptr[index] = value;
2674}
2675
2676
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002677int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002678 ASSERT((index >= 0) && (index < this->length()));
2679 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2680 return ptr[index];
2681}
2682
2683
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002684MaybeObject* ExternalIntArray::get(int index) {
2685 return GetHeap()->NumberFromInt32(get_scalar(index));
2686}
2687
2688
ager@chromium.org3811b432009-10-28 14:53:37 +00002689void ExternalIntArray::set(int index, int32_t value) {
2690 ASSERT((index >= 0) && (index < this->length()));
2691 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2692 ptr[index] = value;
2693}
2694
2695
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002696uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002697 ASSERT((index >= 0) && (index < this->length()));
2698 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2699 return ptr[index];
2700}
2701
2702
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002703MaybeObject* ExternalUnsignedIntArray::get(int index) {
2704 return GetHeap()->NumberFromUint32(get_scalar(index));
2705}
2706
2707
ager@chromium.org3811b432009-10-28 14:53:37 +00002708void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2709 ASSERT((index >= 0) && (index < this->length()));
2710 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2711 ptr[index] = value;
2712}
2713
2714
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002715float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002716 ASSERT((index >= 0) && (index < this->length()));
2717 float* ptr = static_cast<float*>(external_pointer());
2718 return ptr[index];
2719}
2720
2721
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002722MaybeObject* ExternalFloatArray::get(int index) {
2723 return GetHeap()->NumberFromDouble(get_scalar(index));
2724}
2725
2726
ager@chromium.org3811b432009-10-28 14:53:37 +00002727void ExternalFloatArray::set(int index, float value) {
2728 ASSERT((index >= 0) && (index < this->length()));
2729 float* ptr = static_cast<float*>(external_pointer());
2730 ptr[index] = value;
2731}
2732
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002733
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002734double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002735 ASSERT((index >= 0) && (index < this->length()));
2736 double* ptr = static_cast<double*>(external_pointer());
2737 return ptr[index];
2738}
2739
2740
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002741MaybeObject* ExternalDoubleArray::get(int index) {
2742 return GetHeap()->NumberFromDouble(get_scalar(index));
2743}
2744
2745
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002746void ExternalDoubleArray::set(int index, double value) {
2747 ASSERT((index >= 0) && (index < this->length()));
2748 double* ptr = static_cast<double*>(external_pointer());
2749 ptr[index] = value;
2750}
2751
2752
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002753int Map::visitor_id() {
2754 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2755}
2756
2757
2758void Map::set_visitor_id(int id) {
2759 ASSERT(0 <= id && id < 256);
2760 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2761}
2762
ager@chromium.org3811b432009-10-28 14:53:37 +00002763
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002764int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002765 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2766}
2767
2768
2769int Map::inobject_properties() {
2770 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002771}
2772
2773
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002774int Map::pre_allocated_property_fields() {
2775 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2776}
2777
2778
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002779int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002780 int instance_size = map->instance_size();
2781 if (instance_size != kVariableSizeSentinel) return instance_size;
2782 // We can ignore the "symbol" bit becase it is only set for symbols
2783 // and implies a string type.
2784 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002785 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002786 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002787 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002788 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002789 if (instance_type == ASCII_STRING_TYPE) {
2790 return SeqAsciiString::SizeFor(
2791 reinterpret_cast<SeqAsciiString*>(this)->length());
2792 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002793 if (instance_type == BYTE_ARRAY_TYPE) {
2794 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2795 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002796 if (instance_type == FREE_SPACE_TYPE) {
2797 return reinterpret_cast<FreeSpace*>(this)->size();
2798 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002799 if (instance_type == STRING_TYPE) {
2800 return SeqTwoByteString::SizeFor(
2801 reinterpret_cast<SeqTwoByteString*>(this)->length());
2802 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002803 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2804 return FixedDoubleArray::SizeFor(
2805 reinterpret_cast<FixedDoubleArray*>(this)->length());
2806 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002807 ASSERT(instance_type == CODE_TYPE);
2808 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002809}
2810
2811
2812void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002813 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002814 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002815 ASSERT(0 <= value && value < 256);
2816 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2817}
2818
2819
ager@chromium.org7c537e22008-10-16 08:43:32 +00002820void Map::set_inobject_properties(int value) {
2821 ASSERT(0 <= value && value < 256);
2822 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2823}
2824
2825
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002826void Map::set_pre_allocated_property_fields(int value) {
2827 ASSERT(0 <= value && value < 256);
2828 WRITE_BYTE_FIELD(this,
2829 kPreAllocatedPropertyFieldsOffset,
2830 static_cast<byte>(value));
2831}
2832
2833
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002834InstanceType Map::instance_type() {
2835 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2836}
2837
2838
2839void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002840 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2841}
2842
2843
2844int Map::unused_property_fields() {
2845 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2846}
2847
2848
2849void Map::set_unused_property_fields(int value) {
2850 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2851}
2852
2853
2854byte Map::bit_field() {
2855 return READ_BYTE_FIELD(this, kBitFieldOffset);
2856}
2857
2858
2859void Map::set_bit_field(byte value) {
2860 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2861}
2862
2863
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002864byte Map::bit_field2() {
2865 return READ_BYTE_FIELD(this, kBitField2Offset);
2866}
2867
2868
2869void Map::set_bit_field2(byte value) {
2870 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2871}
2872
2873
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002874void Map::set_non_instance_prototype(bool value) {
2875 if (value) {
2876 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2877 } else {
2878 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2879 }
2880}
2881
2882
2883bool Map::has_non_instance_prototype() {
2884 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2885}
2886
2887
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002888void Map::set_function_with_prototype(bool value) {
2889 if (value) {
2890 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2891 } else {
2892 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2893 }
2894}
2895
2896
2897bool Map::function_with_prototype() {
2898 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2899}
2900
2901
ager@chromium.org870a0b62008-11-04 11:43:05 +00002902void Map::set_is_access_check_needed(bool access_check_needed) {
2903 if (access_check_needed) {
2904 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2905 } else {
2906 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2907 }
2908}
2909
2910
2911bool Map::is_access_check_needed() {
2912 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2913}
2914
2915
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002916void Map::set_is_extensible(bool value) {
2917 if (value) {
2918 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2919 } else {
2920 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2921 }
2922}
2923
2924bool Map::is_extensible() {
2925 return ((1 << kIsExtensible) & bit_field2()) != 0;
2926}
2927
2928
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002929void Map::set_attached_to_shared_function_info(bool value) {
2930 if (value) {
2931 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2932 } else {
2933 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2934 }
2935}
2936
2937bool Map::attached_to_shared_function_info() {
2938 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2939}
2940
2941
2942void Map::set_is_shared(bool value) {
2943 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002944 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002945 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002946 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002947 }
2948}
2949
2950bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002951 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002952}
2953
2954
2955JSFunction* Map::unchecked_constructor() {
2956 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2957}
2958
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002959
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002960Code::Flags Code::flags() {
2961 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2962}
2963
2964
2965void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002966 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002967 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002968 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2969 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002970 ExtractArgumentsCountFromFlags(flags) >= 0);
2971 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2972}
2973
2974
2975Code::Kind Code::kind() {
2976 return ExtractKindFromFlags(flags());
2977}
2978
2979
kasper.lund7276f142008-07-30 08:49:36 +00002980InlineCacheState Code::ic_state() {
2981 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002982 // Only allow uninitialized or debugger states for non-IC code
2983 // objects. This is used in the debugger to determine whether or not
2984 // a call to code object has been replaced with a debug break call.
2985 ASSERT(is_inline_cache_stub() ||
2986 result == UNINITIALIZED ||
2987 result == DEBUG_BREAK ||
2988 result == DEBUG_PREPARE_STEP_IN);
2989 return result;
2990}
2991
2992
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002993Code::ExtraICState Code::extra_ic_state() {
2994 ASSERT(is_inline_cache_stub());
2995 return ExtractExtraICStateFromFlags(flags());
2996}
2997
2998
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002999PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003000 return ExtractTypeFromFlags(flags());
3001}
3002
3003
3004int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003005 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003006 return ExtractArgumentsCountFromFlags(flags());
3007}
3008
3009
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003010int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003011 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003012 kind() == UNARY_OP_IC ||
3013 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003014 kind() == COMPARE_IC ||
3015 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003016 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00003017}
3018
3019
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00003020void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003021 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00003022 kind() == UNARY_OP_IC ||
3023 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003024 kind() == COMPARE_IC ||
3025 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00003026 ASSERT(0 <= major && major < 256);
3027 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003028}
3029
3030
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003031bool Code::is_pregenerated() {
3032 return kind() == STUB && IsPregeneratedField::decode(flags());
3033}
3034
3035
3036void Code::set_is_pregenerated(bool value) {
3037 ASSERT(kind() == STUB);
3038 Flags f = flags();
3039 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
3040 set_flags(f);
3041}
3042
3043
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003044bool Code::optimizable() {
3045 ASSERT(kind() == FUNCTION);
3046 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
3047}
3048
3049
3050void Code::set_optimizable(bool value) {
3051 ASSERT(kind() == FUNCTION);
3052 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
3053}
3054
3055
3056bool Code::has_deoptimization_support() {
3057 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00003058 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3059 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003060}
3061
3062
3063void Code::set_has_deoptimization_support(bool value) {
3064 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00003065 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3066 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3067 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3068}
3069
3070
3071bool Code::has_debug_break_slots() {
3072 ASSERT(kind() == FUNCTION);
3073 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3074 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3075}
3076
3077
3078void Code::set_has_debug_break_slots(bool value) {
3079 ASSERT(kind() == FUNCTION);
3080 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3081 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3082 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003083}
3084
3085
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003086bool Code::is_compiled_optimizable() {
3087 ASSERT(kind() == FUNCTION);
3088 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3089 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3090}
3091
3092
3093void Code::set_compiled_optimizable(bool value) {
3094 ASSERT(kind() == FUNCTION);
3095 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3096 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3097 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3098}
3099
3100
yangguo@chromium.orga7d3df92012-02-27 11:46:55 +00003101bool Code::has_self_optimization_header() {
3102 ASSERT(kind() == FUNCTION);
3103 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3104 return FullCodeFlagsHasSelfOptimizationHeader::decode(flags);
3105}
3106
3107
3108void Code::set_self_optimization_header(bool value) {
3109 ASSERT(kind() == FUNCTION);
3110 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3111 flags = FullCodeFlagsHasSelfOptimizationHeader::update(flags, value);
3112 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3113}
3114
3115
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003116int Code::allow_osr_at_loop_nesting_level() {
3117 ASSERT(kind() == FUNCTION);
3118 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3119}
3120
3121
3122void Code::set_allow_osr_at_loop_nesting_level(int level) {
3123 ASSERT(kind() == FUNCTION);
3124 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3125 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3126}
3127
3128
3129unsigned Code::stack_slots() {
3130 ASSERT(kind() == OPTIMIZED_FUNCTION);
3131 return READ_UINT32_FIELD(this, kStackSlotsOffset);
3132}
3133
3134
3135void Code::set_stack_slots(unsigned slots) {
3136 ASSERT(kind() == OPTIMIZED_FUNCTION);
3137 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
3138}
3139
3140
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003141unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003142 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003143 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003144}
3145
3146
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003147void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003148 ASSERT(kind() == OPTIMIZED_FUNCTION);
3149 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003150 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003151}
3152
3153
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003154unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003155 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003156 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003157}
3158
3159
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003160void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003161 ASSERT(kind() == FUNCTION);
3162 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003163 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003164}
3165
3166
3167CheckType Code::check_type() {
3168 ASSERT(is_call_stub() || is_keyed_call_stub());
3169 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3170 return static_cast<CheckType>(type);
3171}
3172
3173
3174void Code::set_check_type(CheckType value) {
3175 ASSERT(is_call_stub() || is_keyed_call_stub());
3176 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3177}
3178
3179
danno@chromium.org40cb8782011-05-25 07:58:50 +00003180byte Code::unary_op_type() {
3181 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003182 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3183}
3184
3185
danno@chromium.org40cb8782011-05-25 07:58:50 +00003186void Code::set_unary_op_type(byte value) {
3187 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003188 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3189}
3190
3191
danno@chromium.org40cb8782011-05-25 07:58:50 +00003192byte Code::binary_op_type() {
3193 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003194 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3195}
3196
3197
danno@chromium.org40cb8782011-05-25 07:58:50 +00003198void Code::set_binary_op_type(byte value) {
3199 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003200 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3201}
3202
3203
danno@chromium.org40cb8782011-05-25 07:58:50 +00003204byte Code::binary_op_result_type() {
3205 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003206 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3207}
3208
3209
danno@chromium.org40cb8782011-05-25 07:58:50 +00003210void Code::set_binary_op_result_type(byte value) {
3211 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003212 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3213}
3214
3215
3216byte Code::compare_state() {
3217 ASSERT(is_compare_ic_stub());
3218 return READ_BYTE_FIELD(this, kCompareStateOffset);
3219}
3220
3221
3222void Code::set_compare_state(byte value) {
3223 ASSERT(is_compare_ic_stub());
3224 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3225}
3226
3227
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003228byte Code::to_boolean_state() {
3229 ASSERT(is_to_boolean_ic_stub());
3230 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3231}
3232
3233
3234void Code::set_to_boolean_state(byte value) {
3235 ASSERT(is_to_boolean_ic_stub());
3236 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3237}
3238
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003239
3240bool Code::has_function_cache() {
3241 ASSERT(kind() == STUB);
3242 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3243}
3244
3245
3246void Code::set_has_function_cache(bool flag) {
3247 ASSERT(kind() == STUB);
3248 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3249}
3250
3251
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003252bool Code::is_inline_cache_stub() {
3253 Kind kind = this->kind();
3254 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3255}
3256
3257
3258Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003259 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003260 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003261 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003262 int argc,
3263 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003264 // Extra IC state is only allowed for call IC stubs or for store IC
3265 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003266 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003267 kind == CALL_IC ||
3268 kind == STORE_IC ||
3269 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003270 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003271 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003272 | ICStateField::encode(ic_state)
3273 | TypeField::encode(type)
3274 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003275 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003276 | CacheHolderField::encode(holder);
3277 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003278}
3279
3280
3281Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3282 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003283 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003284 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003285 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003286 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003287}
3288
3289
3290Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003291 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003292}
3293
3294
kasper.lund7276f142008-07-30 08:49:36 +00003295InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003296 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003297}
3298
3299
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003300Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003301 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003302}
3303
3304
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003305PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003306 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003307}
3308
3309
3310int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003311 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003312}
3313
3314
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003315InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003316 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003317}
3318
3319
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003320Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003321 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003322 return static_cast<Flags>(bits);
3323}
3324
3325
ager@chromium.org8bb60582008-12-11 12:02:20 +00003326Code* Code::GetCodeFromTargetAddress(Address address) {
3327 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3328 // GetCodeFromTargetAddress might be called when marking objects during mark
3329 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3330 // Code::cast. Code::cast does not work when the object's map is
3331 // marked.
3332 Code* result = reinterpret_cast<Code*>(code);
3333 return result;
3334}
3335
3336
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003337Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3338 return HeapObject::
3339 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3340}
3341
3342
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003343Object* Map::prototype() {
3344 return READ_FIELD(this, kPrototypeOffset);
3345}
3346
3347
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003348void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003349 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003350 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003351 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003352}
3353
3354
danno@chromium.org40cb8782011-05-25 07:58:50 +00003355DescriptorArray* Map::instance_descriptors() {
3356 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3357 if (object->IsSmi()) {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003358 return GetHeap()->empty_descriptor_array();
danno@chromium.org40cb8782011-05-25 07:58:50 +00003359 } else {
3360 return DescriptorArray::cast(object);
3361 }
3362}
3363
3364
3365void Map::init_instance_descriptors() {
3366 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3367}
3368
3369
3370void Map::clear_instance_descriptors() {
3371 Object* object = READ_FIELD(this,
3372 kInstanceDescriptorsOrBitField3Offset);
3373 if (!object->IsSmi()) {
3374 WRITE_FIELD(
3375 this,
3376 kInstanceDescriptorsOrBitField3Offset,
3377 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3378 }
3379}
3380
3381
3382void Map::set_instance_descriptors(DescriptorArray* value,
3383 WriteBarrierMode mode) {
3384 Object* object = READ_FIELD(this,
3385 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003386 Heap* heap = GetHeap();
3387 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003388 clear_instance_descriptors();
3389 return;
3390 } else {
3391 if (object->IsSmi()) {
3392 value->set_bit_field3_storage(Smi::cast(object)->value());
3393 } else {
3394 value->set_bit_field3_storage(
3395 DescriptorArray::cast(object)->bit_field3_storage());
3396 }
3397 }
3398 ASSERT(!is_shared());
3399 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003400 CONDITIONAL_WRITE_BARRIER(
3401 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003402}
3403
3404
3405int Map::bit_field3() {
3406 Object* object = READ_FIELD(this,
3407 kInstanceDescriptorsOrBitField3Offset);
3408 if (object->IsSmi()) {
3409 return Smi::cast(object)->value();
3410 } else {
3411 return DescriptorArray::cast(object)->bit_field3_storage();
3412 }
3413}
3414
3415
3416void Map::set_bit_field3(int value) {
3417 ASSERT(Smi::IsValid(value));
3418 Object* object = READ_FIELD(this,
3419 kInstanceDescriptorsOrBitField3Offset);
3420 if (object->IsSmi()) {
3421 WRITE_FIELD(this,
3422 kInstanceDescriptorsOrBitField3Offset,
3423 Smi::FromInt(value));
3424 } else {
3425 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3426 }
3427}
3428
3429
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003430FixedArray* Map::unchecked_prototype_transitions() {
3431 return reinterpret_cast<FixedArray*>(
3432 READ_FIELD(this, kPrototypeTransitionsOffset));
3433}
3434
3435
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003436ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003437ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003438ACCESSORS(Map, constructor, Object, kConstructorOffset)
3439
3440ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003441ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003442ACCESSORS(JSFunction,
3443 next_function_link,
3444 Object,
3445 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003446
3447ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3448ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003449ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003450
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003451ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003452
3453ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3454ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3455ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3456ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3457ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3458
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00003459ACCESSORS(AccessorPair, getter, Object, kGetterOffset)
3460ACCESSORS(AccessorPair, setter, Object, kSetterOffset)
3461
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003462ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3463ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3464ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3465
3466ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3467ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3468ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3469ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3470ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3471ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3472
3473ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3474ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3475
3476ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3477ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3478
3479ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3480ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003481ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3482 kPropertyAccessorsOffset)
3483ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3484 kPrototypeTemplateOffset)
3485ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3486ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3487 kNamedPropertyHandlerOffset)
3488ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3489 kIndexedPropertyHandlerOffset)
3490ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3491 kInstanceTemplateOffset)
3492ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3493ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003494ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3495 kInstanceCallHandlerOffset)
3496ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3497 kAccessCheckInfoOffset)
3498ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3499
3500ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003501ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3502 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003503
3504ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3505ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3506
3507ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3508
3509ACCESSORS(Script, source, Object, kSourceOffset)
3510ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003511ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003512ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3513ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003514ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003515ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003516ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003517ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003518ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003519ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003520ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003521ACCESSORS(Script, eval_from_instructions_offset, Smi,
3522 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003523
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003524#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003525ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3526ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3527ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3528ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3529
3530ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3531ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3532ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3533ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003534#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003535
3536ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003537ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3538ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003539ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3540 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003541ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003542ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3543ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003544ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003545ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3546 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003547
yangguo@chromium.org78d1ad42012-02-09 13:53:47 +00003548SMI_ACCESSORS(SharedFunctionInfo, profiler_ticks, kProfilerTicksOffset)
3549
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003550BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3551 kHiddenPrototypeBit)
3552BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3553BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3554 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003555BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3556 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003557BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3558 kIsExpressionBit)
3559BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3560 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003561BOOL_GETTER(SharedFunctionInfo,
3562 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003563 has_only_simple_this_property_assignments,
3564 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003565BOOL_ACCESSORS(SharedFunctionInfo,
3566 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003567 allows_lazy_compilation,
3568 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003569BOOL_ACCESSORS(SharedFunctionInfo,
3570 compiler_hints,
3571 uses_arguments,
3572 kUsesArguments)
3573BOOL_ACCESSORS(SharedFunctionInfo,
3574 compiler_hints,
3575 has_duplicate_parameters,
3576 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003577
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003578
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003579#if V8_HOST_ARCH_32_BIT
3580SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3581SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003582 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003583SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003584 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003585SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3586SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003587 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003588SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3589SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003590 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003591SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003592 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003593SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003594 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003595SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003596SMI_ACCESSORS(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3597SMI_ACCESSORS(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003598#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003599
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003600#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003601 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003602 int holder::name() { \
3603 int value = READ_INT_FIELD(this, offset); \
3604 ASSERT(kHeapObjectTag == 1); \
3605 ASSERT((value & kHeapObjectTag) == 0); \
3606 return value >> 1; \
3607 } \
3608 void holder::set_##name(int value) { \
3609 ASSERT(kHeapObjectTag == 1); \
3610 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3611 (value & 0xC0000000) == 0x000000000); \
3612 WRITE_INT_FIELD(this, \
3613 offset, \
3614 (value << 1) & ~kHeapObjectTag); \
3615 }
3616
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003617#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3618 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003619 INT_ACCESSORS(holder, name, offset)
3620
3621
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003622PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003623PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3624 formal_parameter_count,
3625 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003626
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003627PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3628 expected_nof_properties,
3629 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003630PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3631
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003632PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3633PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3634 start_position_and_type,
3635 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003636
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003637PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3638 function_token_position,
3639 kFunctionTokenPositionOffset)
3640PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3641 compiler_hints,
3642 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003643
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003644PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3645 this_property_assignments_count,
3646 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003647PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003648
3649PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, ast_node_count, kAstNodeCountOffset)
3650PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, deopt_counter, kDeoptCounterOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003651#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003652
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003653
3654int SharedFunctionInfo::construction_count() {
3655 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3656}
3657
3658
3659void SharedFunctionInfo::set_construction_count(int value) {
3660 ASSERT(0 <= value && value < 256);
3661 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3662}
3663
3664
whesse@chromium.org7b260152011-06-20 15:33:18 +00003665BOOL_ACCESSORS(SharedFunctionInfo,
3666 compiler_hints,
3667 live_objects_may_exist,
3668 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003669
3670
3671bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00003672 return initial_map() != GetHeap()->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003673}
3674
3675
whesse@chromium.org7b260152011-06-20 15:33:18 +00003676BOOL_GETTER(SharedFunctionInfo,
3677 compiler_hints,
3678 optimization_disabled,
3679 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003680
3681
3682void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3683 set_compiler_hints(BooleanBit::set(compiler_hints(),
3684 kOptimizationDisabled,
3685 disable));
3686 // If disabling optimizations we reflect that in the code object so
3687 // it will not be counted as optimizable code.
3688 if ((code()->kind() == Code::FUNCTION) && disable) {
3689 code()->set_optimizable(false);
3690 }
3691}
3692
3693
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003694LanguageMode SharedFunctionInfo::language_mode() {
3695 int hints = compiler_hints();
3696 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3697 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3698 return EXTENDED_MODE;
3699 }
3700 return BooleanBit::get(hints, kStrictModeFunction)
3701 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003702}
3703
3704
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003705void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3706 // We only allow language mode transitions that go set the same language mode
3707 // again or go up in the chain:
3708 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3709 ASSERT(this->language_mode() == CLASSIC_MODE ||
3710 this->language_mode() == language_mode ||
3711 language_mode == EXTENDED_MODE);
3712 int hints = compiler_hints();
3713 hints = BooleanBit::set(
3714 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3715 hints = BooleanBit::set(
3716 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3717 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003718}
3719
3720
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003721bool SharedFunctionInfo::is_classic_mode() {
3722 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3723}
3724
3725BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3726 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003727BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3728BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3729 name_should_print_as_anonymous,
3730 kNameShouldPrintAsAnonymous)
3731BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3732BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
yangguo@chromium.org56454712012-02-16 15:33:53 +00003733BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_function, kIsFunction)
3734BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_optimize,
3735 kDontOptimize)
svenpanne@chromium.orgb1df11d2012-02-08 10:26:21 +00003736BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, dont_inline, kDontInline)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003737
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003738ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3739ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3740
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003741ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3742
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003743bool Script::HasValidSource() {
3744 Object* src = this->source();
3745 if (!src->IsString()) return true;
3746 String* src_str = String::cast(src);
3747 if (!StringShape(src_str).IsExternal()) return true;
3748 if (src_str->IsAsciiRepresentation()) {
3749 return ExternalAsciiString::cast(src)->resource() != NULL;
3750 } else if (src_str->IsTwoByteRepresentation()) {
3751 return ExternalTwoByteString::cast(src)->resource() != NULL;
3752 }
3753 return true;
3754}
3755
3756
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003757void SharedFunctionInfo::DontAdaptArguments() {
3758 ASSERT(code()->kind() == Code::BUILTIN);
3759 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3760}
3761
3762
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003763int SharedFunctionInfo::start_position() {
3764 return start_position_and_type() >> kStartPositionShift;
3765}
3766
3767
3768void SharedFunctionInfo::set_start_position(int start_position) {
3769 set_start_position_and_type((start_position << kStartPositionShift)
3770 | (start_position_and_type() & ~kStartPositionMask));
3771}
3772
3773
3774Code* SharedFunctionInfo::code() {
3775 return Code::cast(READ_FIELD(this, kCodeOffset));
3776}
3777
3778
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003779Code* SharedFunctionInfo::unchecked_code() {
3780 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3781}
3782
3783
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003784void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003785 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003786 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003787}
3788
3789
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003790ScopeInfo* SharedFunctionInfo::scope_info() {
3791 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003792}
3793
3794
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003795void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003796 WriteBarrierMode mode) {
3797 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003798 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3799 this,
3800 kScopeInfoOffset,
3801 reinterpret_cast<Object*>(value),
3802 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003803}
3804
3805
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003806bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003807 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003808 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003809}
3810
3811
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003812bool SharedFunctionInfo::IsApiFunction() {
3813 return function_data()->IsFunctionTemplateInfo();
3814}
3815
3816
3817FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3818 ASSERT(IsApiFunction());
3819 return FunctionTemplateInfo::cast(function_data());
3820}
3821
3822
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003823bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003824 return function_data()->IsSmi();
3825}
3826
3827
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003828BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3829 ASSERT(HasBuiltinFunctionId());
3830 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003831}
3832
3833
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003834int SharedFunctionInfo::code_age() {
3835 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3836}
3837
3838
3839void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00003840 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
3841 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003842}
3843
3844
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003845bool SharedFunctionInfo::has_deoptimization_support() {
3846 Code* code = this->code();
3847 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3848}
3849
3850
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003851bool JSFunction::IsBuiltin() {
3852 return context()->global()->IsJSBuiltinsObject();
3853}
3854
3855
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003856bool JSFunction::NeedsArgumentsAdaption() {
3857 return shared()->formal_parameter_count() !=
3858 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3859}
3860
3861
3862bool JSFunction::IsOptimized() {
3863 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3864}
3865
3866
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003867bool JSFunction::IsOptimizable() {
3868 return code()->kind() == Code::FUNCTION && code()->optimizable();
3869}
3870
3871
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003872bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003873 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003874}
3875
3876
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003877Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003878 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003879}
3880
3881
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003882Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003883 return reinterpret_cast<Code*>(
3884 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003885}
3886
3887
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003888void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003889 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003890 Address entry = value->entry();
3891 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003892 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3893 this,
3894 HeapObject::RawField(this, kCodeEntryOffset),
3895 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003896}
3897
3898
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003899void JSFunction::ReplaceCode(Code* code) {
3900 bool was_optimized = IsOptimized();
3901 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3902
3903 set_code(code);
3904
3905 // Add/remove the function from the list of optimized functions for this
3906 // context based on the state change.
3907 if (!was_optimized && is_optimized) {
3908 context()->global_context()->AddOptimizedFunction(this);
3909 }
3910 if (was_optimized && !is_optimized) {
3911 context()->global_context()->RemoveOptimizedFunction(this);
3912 }
3913}
3914
3915
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003916Context* JSFunction::context() {
3917 return Context::cast(READ_FIELD(this, kContextOffset));
3918}
3919
3920
3921Object* JSFunction::unchecked_context() {
3922 return READ_FIELD(this, kContextOffset);
3923}
3924
3925
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003926SharedFunctionInfo* JSFunction::unchecked_shared() {
3927 return reinterpret_cast<SharedFunctionInfo*>(
3928 READ_FIELD(this, kSharedFunctionInfoOffset));
3929}
3930
3931
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003932void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003933 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003934 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003935 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003936}
3937
3938ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3939 kPrototypeOrInitialMapOffset)
3940
3941
3942Map* JSFunction::initial_map() {
3943 return Map::cast(prototype_or_initial_map());
3944}
3945
3946
3947void JSFunction::set_initial_map(Map* value) {
3948 set_prototype_or_initial_map(value);
3949}
3950
3951
danno@chromium.orgfa458e42012-02-01 10:48:36 +00003952MaybeObject* JSFunction::set_initial_map_and_cache_transitions(
3953 Map* initial_map) {
3954 Context* global_context = context()->global_context();
3955 Object* array_function =
3956 global_context->get(Context::ARRAY_FUNCTION_INDEX);
3957 if (array_function->IsJSFunction() &&
3958 this == JSFunction::cast(array_function)) {
3959 ASSERT(initial_map->elements_kind() == FAST_SMI_ONLY_ELEMENTS);
3960
3961 MaybeObject* maybe_map = initial_map->CopyDropTransitions();
3962 Map* new_double_map = NULL;
3963 if (!maybe_map->To<Map>(&new_double_map)) return maybe_map;
3964 new_double_map->set_elements_kind(FAST_DOUBLE_ELEMENTS);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00003965 maybe_map = initial_map->AddElementsTransition(FAST_DOUBLE_ELEMENTS,
3966 new_double_map);
3967 if (maybe_map->IsFailure()) return maybe_map;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00003968
3969 maybe_map = new_double_map->CopyDropTransitions();
3970 Map* new_object_map = NULL;
3971 if (!maybe_map->To<Map>(&new_object_map)) return maybe_map;
3972 new_object_map->set_elements_kind(FAST_ELEMENTS);
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00003973 maybe_map = new_double_map->AddElementsTransition(FAST_ELEMENTS,
3974 new_object_map);
3975 if (maybe_map->IsFailure()) return maybe_map;
danno@chromium.orgfa458e42012-02-01 10:48:36 +00003976
3977 global_context->set_smi_js_array_map(initial_map);
3978 global_context->set_double_js_array_map(new_double_map);
3979 global_context->set_object_js_array_map(new_object_map);
3980 }
3981 set_initial_map(initial_map);
3982 return this;
3983}
3984
3985
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003986bool JSFunction::has_initial_map() {
3987 return prototype_or_initial_map()->IsMap();
3988}
3989
3990
3991bool JSFunction::has_instance_prototype() {
3992 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3993}
3994
3995
3996bool JSFunction::has_prototype() {
3997 return map()->has_non_instance_prototype() || has_instance_prototype();
3998}
3999
4000
4001Object* JSFunction::instance_prototype() {
4002 ASSERT(has_instance_prototype());
4003 if (has_initial_map()) return initial_map()->prototype();
4004 // When there is no initial map and the prototype is a JSObject, the
4005 // initial map field is used for the prototype field.
4006 return prototype_or_initial_map();
4007}
4008
4009
4010Object* JSFunction::prototype() {
4011 ASSERT(has_prototype());
4012 // If the function's prototype property has been set to a non-JSObject
4013 // value, that value is stored in the constructor field of the map.
4014 if (map()->has_non_instance_prototype()) return map()->constructor();
4015 return instance_prototype();
4016}
4017
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00004018bool JSFunction::should_have_prototype() {
4019 return map()->function_with_prototype();
4020}
4021
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004022
4023bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00004024 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004025}
4026
4027
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004028FixedArray* JSFunction::literals() {
4029 ASSERT(!shared()->bound());
4030 return literals_or_bindings();
4031}
4032
4033
4034void JSFunction::set_literals(FixedArray* literals) {
4035 ASSERT(!shared()->bound());
4036 set_literals_or_bindings(literals);
4037}
4038
4039
4040FixedArray* JSFunction::function_bindings() {
4041 ASSERT(shared()->bound());
4042 return literals_or_bindings();
4043}
4044
4045
4046void JSFunction::set_function_bindings(FixedArray* bindings) {
4047 ASSERT(shared()->bound());
4048 // Bound function literal may be initialized to the empty fixed array
4049 // before the bindings are set.
4050 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
4051 bindings->map() == GetHeap()->fixed_cow_array_map());
4052 set_literals_or_bindings(bindings);
4053}
4054
4055
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004056int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004057 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004058 return literals()->length();
4059}
4060
4061
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004062Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004063 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004064 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004065}
4066
4067
4068void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
4069 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004070 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004071 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004072 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004073}
4074
4075
4076Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004077 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004078 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
4079}
4080
4081
4082void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
4083 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00004084 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00004085 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004086 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004087}
4088
4089
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004090ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004091ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00004092ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
4093ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
4094
4095
4096void JSProxy::InitializeBody(int object_size, Object* value) {
4097 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
4098 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
4099 WRITE_FIELD(this, offset, value);
4100 }
4101}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004102
4103
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004104ACCESSORS(JSSet, table, Object, kTableOffset)
4105ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004106ACCESSORS(JSWeakMap, table, Object, kTableOffset)
4107ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004108
4109
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004110Address Foreign::foreign_address() {
4111 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004112}
4113
4114
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004115void Foreign::set_foreign_address(Address value) {
4116 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004117}
4118
4119
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004120ACCESSORS(JSValue, value, Object, kValueOffset)
4121
4122
4123JSValue* JSValue::cast(Object* obj) {
4124 ASSERT(obj->IsJSValue());
4125 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4126 return reinterpret_cast<JSValue*>(obj);
4127}
4128
4129
svenpanne@chromium.org4efbdb12012-03-12 08:18:42 +00004130ACCESSORS(JSDate, value, Object, kValueOffset)
4131ACCESSORS(JSDate, cache_stamp, Object, kCacheStampOffset)
4132ACCESSORS(JSDate, year, Object, kYearOffset)
4133ACCESSORS(JSDate, month, Object, kMonthOffset)
4134ACCESSORS(JSDate, day, Object, kDayOffset)
4135ACCESSORS(JSDate, weekday, Object, kWeekdayOffset)
4136ACCESSORS(JSDate, hour, Object, kHourOffset)
4137ACCESSORS(JSDate, min, Object, kMinOffset)
4138ACCESSORS(JSDate, sec, Object, kSecOffset)
4139
4140
4141JSDate* JSDate::cast(Object* obj) {
4142 ASSERT(obj->IsJSDate());
4143 ASSERT(HeapObject::cast(obj)->Size() == JSDate::kSize);
4144 return reinterpret_cast<JSDate*>(obj);
4145}
4146
4147
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004148ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4149ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4150ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4151ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4152ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4153SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4154SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4155
4156
4157JSMessageObject* JSMessageObject::cast(Object* obj) {
4158 ASSERT(obj->IsJSMessageObject());
4159 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4160 return reinterpret_cast<JSMessageObject*>(obj);
4161}
4162
4163
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004164INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004165ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004166ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004167ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004168ACCESSORS(Code, type_feedback_info, Object, kTypeFeedbackInfoOffset)
yangguo@chromium.org659ceec2012-01-26 07:37:54 +00004169ACCESSORS(Code, gc_metadata, Object, kGCMetadataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004170
4171
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004172byte* Code::instruction_start() {
4173 return FIELD_ADDR(this, kHeaderSize);
4174}
4175
4176
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004177byte* Code::instruction_end() {
4178 return instruction_start() + instruction_size();
4179}
4180
4181
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004182int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004183 return RoundUp(instruction_size(), kObjectAlignment);
4184}
4185
4186
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004187FixedArray* Code::unchecked_deoptimization_data() {
4188 return reinterpret_cast<FixedArray*>(
4189 READ_FIELD(this, kDeoptimizationDataOffset));
4190}
4191
4192
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004193ByteArray* Code::unchecked_relocation_info() {
4194 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004195}
4196
4197
4198byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004199 return unchecked_relocation_info()->GetDataStartAddress();
4200}
4201
4202
4203int Code::relocation_size() {
4204 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004205}
4206
4207
4208byte* Code::entry() {
4209 return instruction_start();
4210}
4211
4212
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004213bool Code::contains(byte* inner_pointer) {
4214 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004215}
4216
4217
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004218ACCESSORS(JSArray, length, Object, kLengthOffset)
4219
4220
ager@chromium.org236ad962008-09-25 09:45:57 +00004221ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004222
4223
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004224JSRegExp::Type JSRegExp::TypeTag() {
4225 Object* data = this->data();
4226 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4227 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4228 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004229}
4230
4231
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004232JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4233 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4234 return static_cast<JSRegExp::Type>(smi->value());
4235}
4236
4237
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004238int JSRegExp::CaptureCount() {
4239 switch (TypeTag()) {
4240 case ATOM:
4241 return 0;
4242 case IRREGEXP:
4243 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4244 default:
4245 UNREACHABLE();
4246 return -1;
4247 }
4248}
4249
4250
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004251JSRegExp::Flags JSRegExp::GetFlags() {
4252 ASSERT(this->data()->IsFixedArray());
4253 Object* data = this->data();
4254 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4255 return Flags(smi->value());
4256}
4257
4258
4259String* JSRegExp::Pattern() {
4260 ASSERT(this->data()->IsFixedArray());
4261 Object* data = this->data();
4262 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4263 return pattern;
4264}
4265
4266
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004267Object* JSRegExp::DataAt(int index) {
4268 ASSERT(TypeTag() != NOT_COMPILED);
4269 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004270}
4271
4272
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004273Object* JSRegExp::DataAtUnchecked(int index) {
4274 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4275 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4276 return READ_FIELD(fa, offset);
4277}
4278
4279
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004280void JSRegExp::SetDataAt(int index, Object* value) {
4281 ASSERT(TypeTag() != NOT_COMPILED);
4282 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4283 FixedArray::cast(data())->set(index, value);
4284}
4285
4286
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004287void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4288 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4289 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4290 if (value->IsSmi()) {
4291 fa->set_unchecked(index, Smi::cast(value));
4292 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004293 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004294 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4295 }
4296}
4297
4298
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004299ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004300 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004301#if DEBUG
4302 FixedArrayBase* fixed_array =
4303 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4304 Map* map = fixed_array->map();
4305 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004306 (map == GetHeap()->fixed_array_map() ||
4307 map == GetHeap()->fixed_cow_array_map())) ||
4308 (kind == FAST_DOUBLE_ELEMENTS &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004309 (fixed_array->IsFixedDoubleArray() ||
4310 fixed_array == GetHeap()->empty_fixed_array())) ||
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004311 (kind == DICTIONARY_ELEMENTS &&
4312 fixed_array->IsFixedArray() &&
4313 fixed_array->IsDictionary()) ||
4314 (kind > DICTIONARY_ELEMENTS));
4315 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4316 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004317#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004318 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004319}
4320
4321
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004322ElementsAccessor* JSObject::GetElementsAccessor() {
4323 return ElementsAccessor::ForKind(GetElementsKind());
4324}
4325
4326
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004327bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004328 return GetElementsKind() == FAST_ELEMENTS;
4329}
4330
4331
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004332bool JSObject::HasFastSmiOnlyElements() {
4333 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4334}
4335
4336
4337bool JSObject::HasFastTypeElements() {
4338 ElementsKind elements_kind = GetElementsKind();
4339 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4340 elements_kind == FAST_ELEMENTS;
4341}
4342
4343
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004344bool JSObject::HasFastDoubleElements() {
4345 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4346}
4347
4348
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004349bool JSObject::HasDictionaryElements() {
4350 return GetElementsKind() == DICTIONARY_ELEMENTS;
4351}
4352
4353
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004354bool JSObject::HasNonStrictArgumentsElements() {
4355 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4356}
4357
4358
ager@chromium.org3811b432009-10-28 14:53:37 +00004359bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004360 HeapObject* array = elements();
4361 ASSERT(array != NULL);
4362 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004363}
4364
4365
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004366#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4367bool JSObject::HasExternal##name##Elements() { \
4368 HeapObject* array = elements(); \
4369 ASSERT(array != NULL); \
4370 if (!array->IsHeapObject()) \
4371 return false; \
4372 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004373}
4374
4375
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004376EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4377EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4378EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4379EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4380 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4381EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4382EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4383 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4384EXTERNAL_ELEMENTS_CHECK(Float,
4385 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004386EXTERNAL_ELEMENTS_CHECK(Double,
4387 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004388EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004389
4390
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004391bool JSObject::HasNamedInterceptor() {
4392 return map()->has_named_interceptor();
4393}
4394
4395
4396bool JSObject::HasIndexedInterceptor() {
4397 return map()->has_indexed_interceptor();
4398}
4399
4400
lrn@chromium.org303ada72010-10-27 09:33:13 +00004401MaybeObject* JSObject::EnsureWritableFastElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004402 ASSERT(HasFastTypeElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004403 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004404 Isolate* isolate = GetIsolate();
4405 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004406 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004407 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4408 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004409 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4410 return maybe_writable_elems;
4411 }
4412 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004413 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004414 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004415 return writable_elems;
4416}
4417
4418
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004419StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004420 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004421 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004422}
4423
4424
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004425SeededNumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004426 ASSERT(HasDictionaryElements());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004427 return SeededNumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004428}
4429
4430
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004431bool String::IsHashFieldComputed(uint32_t field) {
4432 return (field & kHashNotComputedMask) == 0;
4433}
4434
4435
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004436bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004437 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004438}
4439
4440
4441uint32_t String::Hash() {
4442 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004443 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004444 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004445 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004446 return ComputeAndSetHash();
4447}
4448
4449
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004450StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004451 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004452 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004453 array_index_(0),
4454 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4455 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004456 is_valid_(true) {
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004457 ASSERT(FLAG_randomize_hashes || raw_running_hash_ == 0);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004458}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004459
4460
4461bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004462 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004463}
4464
4465
4466void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004467 // Use the Jenkins one-at-a-time hash function to update the hash
4468 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004469 raw_running_hash_ += c;
4470 raw_running_hash_ += (raw_running_hash_ << 10);
4471 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004472 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004473 if (is_array_index_) {
4474 if (c < '0' || c > '9') {
4475 is_array_index_ = false;
4476 } else {
4477 int d = c - '0';
4478 if (is_first_char_) {
4479 is_first_char_ = false;
4480 if (c == '0' && length_ > 1) {
4481 is_array_index_ = false;
4482 return;
4483 }
4484 }
4485 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4486 is_array_index_ = false;
4487 } else {
4488 array_index_ = array_index_ * 10 + d;
4489 }
4490 }
4491 }
4492}
4493
4494
4495void StringHasher::AddCharacterNoIndex(uc32 c) {
4496 ASSERT(!is_array_index());
4497 raw_running_hash_ += c;
4498 raw_running_hash_ += (raw_running_hash_ << 10);
4499 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4500}
4501
4502
4503uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004504 // Get the calculated raw hash value and do some more bit ops to distribute
4505 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004506 uint32_t result = raw_running_hash_;
4507 result += (result << 3);
4508 result ^= (result >> 11);
4509 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004510 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004511 result = 27;
4512 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004513 return result;
4514}
4515
4516
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004517template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004518uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4519 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004520 if (!hasher.has_trivial_hash()) {
4521 int i;
4522 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4523 hasher.AddCharacter(chars[i]);
4524 }
4525 for (; i < length; i++) {
4526 hasher.AddCharacterNoIndex(chars[i]);
4527 }
4528 }
4529 return hasher.GetHashField();
4530}
4531
4532
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004533bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004534 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004535 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4536 return false;
4537 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004538 return SlowAsArrayIndex(index);
4539}
4540
4541
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004542Object* JSReceiver::GetPrototype() {
4543 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004544}
4545
4546
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004547bool JSReceiver::HasProperty(String* name) {
4548 if (IsJSProxy()) {
4549 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4550 }
4551 return GetPropertyAttribute(name) != ABSENT;
4552}
4553
4554
4555bool JSReceiver::HasLocalProperty(String* name) {
4556 if (IsJSProxy()) {
4557 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4558 }
4559 return GetLocalPropertyAttribute(name) != ABSENT;
4560}
4561
4562
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004563PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004564 return GetPropertyAttributeWithReceiver(this, key);
4565}
4566
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004567// TODO(504): this may be useful in other places too where JSGlobalProxy
4568// is used.
4569Object* JSObject::BypassGlobalProxy() {
4570 if (IsJSGlobalProxy()) {
4571 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004572 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004573 ASSERT(proto->IsJSGlobalObject());
4574 return proto;
4575 }
4576 return this;
4577}
4578
4579
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004580MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4581 return IsJSProxy()
4582 ? JSProxy::cast(this)->GetIdentityHash(flag)
4583 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004584}
4585
4586
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004587bool JSReceiver::HasElement(uint32_t index) {
4588 if (IsJSProxy()) {
4589 return JSProxy::cast(this)->HasElementWithHandler(index);
4590 }
4591 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004592}
4593
4594
4595bool AccessorInfo::all_can_read() {
4596 return BooleanBit::get(flag(), kAllCanReadBit);
4597}
4598
4599
4600void AccessorInfo::set_all_can_read(bool value) {
4601 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4602}
4603
4604
4605bool AccessorInfo::all_can_write() {
4606 return BooleanBit::get(flag(), kAllCanWriteBit);
4607}
4608
4609
4610void AccessorInfo::set_all_can_write(bool value) {
4611 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4612}
4613
4614
ager@chromium.org870a0b62008-11-04 11:43:05 +00004615bool AccessorInfo::prohibits_overwriting() {
4616 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4617}
4618
4619
4620void AccessorInfo::set_prohibits_overwriting(bool value) {
4621 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4622}
4623
4624
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004625PropertyAttributes AccessorInfo::property_attributes() {
4626 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4627}
4628
4629
4630void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004631 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004632}
4633
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004634
4635template<typename Shape, typename Key>
4636void Dictionary<Shape, Key>::SetEntry(int entry,
4637 Object* key,
4638 Object* value) {
4639 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4640}
4641
4642
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004643template<typename Shape, typename Key>
4644void Dictionary<Shape, Key>::SetEntry(int entry,
4645 Object* key,
4646 Object* value,
4647 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004648 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004649 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004650 AssertNoAllocation no_gc;
4651 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004652 FixedArray::set(index, key, mode);
4653 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004654 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004655}
4656
4657
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004658bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4659 ASSERT(other->IsNumber());
4660 return key == static_cast<uint32_t>(other->Number());
4661}
4662
4663
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004664uint32_t UnseededNumberDictionaryShape::Hash(uint32_t key) {
4665 return ComputeIntegerHash(key, 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004666}
4667
4668
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004669uint32_t UnseededNumberDictionaryShape::HashForObject(uint32_t key,
4670 Object* other) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004671 ASSERT(other->IsNumber());
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004672 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), 0);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004673}
4674
erik.corry@gmail.comf2038fb2012-01-16 11:42:08 +00004675uint32_t SeededNumberDictionaryShape::SeededHash(uint32_t key, uint32_t seed) {
4676 return ComputeIntegerHash(key, seed);
4677}
4678
4679uint32_t SeededNumberDictionaryShape::SeededHashForObject(uint32_t key,
4680 uint32_t seed,
4681 Object* other) {
4682 ASSERT(other->IsNumber());
4683 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()), seed);
4684}
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004685
4686MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4687 return Isolate::Current()->heap()->NumberFromUint32(key);
4688}
4689
4690
4691bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4692 // We know that all entries in a hash table had their hash keys created.
4693 // Use that knowledge to have fast failure.
4694 if (key->Hash() != String::cast(other)->Hash()) return false;
4695 return key->Equals(String::cast(other));
4696}
4697
4698
4699uint32_t StringDictionaryShape::Hash(String* key) {
4700 return key->Hash();
4701}
4702
4703
4704uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4705 return String::cast(other)->Hash();
4706}
4707
4708
4709MaybeObject* StringDictionaryShape::AsObject(String* key) {
4710 return key;
4711}
4712
4713
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004714template <int entrysize>
4715bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4716 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004717}
4718
4719
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004720template <int entrysize>
4721uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004722 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4723 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004724}
4725
4726
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004727template <int entrysize>
4728uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4729 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004730 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4731 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004732}
4733
4734
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004735template <int entrysize>
4736MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004737 return key;
4738}
4739
4740
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004741void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004742 // No write barrier is needed since empty_fixed_array is not in new space.
4743 // Please note this function is used during marking:
4744 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004745 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4746 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004747}
4748
4749
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004750void JSArray::EnsureSize(int required_size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004751 ASSERT(HasFastTypeElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004752 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004753 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4754 if (elts->length() < required_size) {
4755 // Doubling in size would be overkill, but leave some slack to avoid
4756 // constantly growing.
4757 Expand(required_size + (required_size >> 3));
4758 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004759 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004760 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4761 // Expand will allocate a new backing store in new space even if the size
4762 // we asked for isn't larger than what we had before.
4763 Expand(required_size);
4764 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004765}
4766
4767
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004768void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004769 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004770 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4771}
4772
4773
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004774bool JSArray::AllowsSetElementsLength() {
4775 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
4776 ASSERT(result == !HasExternalArrayElements());
4777 return result;
4778}
4779
4780
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004781MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
4782 MaybeObject* maybe_result = EnsureCanContainElements(
4783 storage, ALLOW_COPIED_DOUBLE_ELEMENTS);
4784 if (maybe_result->IsFailure()) return maybe_result;
4785 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
4786 GetElementsKind() == FAST_DOUBLE_ELEMENTS) ||
4787 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
4788 ((GetElementsKind() == FAST_ELEMENTS) ||
4789 (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS &&
4790 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004791 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004792 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004793 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004794}
4795
4796
lrn@chromium.org303ada72010-10-27 09:33:13 +00004797MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004798 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004799 return GetHeap()->CopyFixedArray(this);
4800}
4801
4802
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004803MaybeObject* FixedDoubleArray::Copy() {
4804 if (length() == 0) return this;
4805 return GetHeap()->CopyFixedDoubleArray(this);
4806}
4807
4808
danno@chromium.orgfa458e42012-02-01 10:48:36 +00004809void TypeFeedbackCells::SetAstId(int index, Smi* id) {
4810 set(1 + index * 2, id);
4811}
4812
4813
4814Smi* TypeFeedbackCells::AstId(int index) {
4815 return Smi::cast(get(1 + index * 2));
4816}
4817
4818
4819void TypeFeedbackCells::SetCell(int index, JSGlobalPropertyCell* cell) {
4820 set(index * 2, cell);
4821}
4822
4823
4824JSGlobalPropertyCell* TypeFeedbackCells::Cell(int index) {
4825 return JSGlobalPropertyCell::cast(get(index * 2));
4826}
4827
4828
4829Handle<Object> TypeFeedbackCells::UninitializedSentinel(Isolate* isolate) {
4830 return isolate->factory()->the_hole_value();
4831}
4832
4833
4834Handle<Object> TypeFeedbackCells::MegamorphicSentinel(Isolate* isolate) {
4835 return isolate->factory()->undefined_value();
4836}
4837
4838
4839Object* TypeFeedbackCells::RawUninitializedSentinel(Heap* heap) {
4840 return heap->raw_unchecked_the_hole_value();
4841}
4842
4843
jkummerow@chromium.orgf7a58842012-02-21 10:08:21 +00004844SMI_ACCESSORS(TypeFeedbackInfo, ic_total_count, kIcTotalCountOffset)
4845SMI_ACCESSORS(TypeFeedbackInfo, ic_with_typeinfo_count,
4846 kIcWithTypeinfoCountOffset)
4847ACCESSORS(TypeFeedbackInfo, type_feedback_cells, TypeFeedbackCells,
4848 kTypeFeedbackCellsOffset)
4849
4850
yangguo@chromium.orgab30bb82012-02-24 14:41:46 +00004851SMI_ACCESSORS(AliasedArgumentsEntry, aliased_context_slot, kAliasedContextSlot)
4852
4853
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004854Relocatable::Relocatable(Isolate* isolate) {
4855 ASSERT(isolate == Isolate::Current());
4856 isolate_ = isolate;
4857 prev_ = isolate->relocatable_top();
4858 isolate->set_relocatable_top(this);
4859}
4860
4861
4862Relocatable::~Relocatable() {
4863 ASSERT(isolate_ == Isolate::Current());
4864 ASSERT_EQ(isolate_->relocatable_top(), this);
4865 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004866}
4867
4868
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004869int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4870 return map->instance_size();
4871}
4872
4873
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004874void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004875 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004876 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004877}
4878
4879
4880template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004881void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004882 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004883 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004884}
4885
4886
4887void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4888 typedef v8::String::ExternalAsciiStringResource Resource;
4889 v->VisitExternalAsciiString(
4890 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4891}
4892
4893
4894template<typename StaticVisitor>
4895void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4896 typedef v8::String::ExternalAsciiStringResource Resource;
4897 StaticVisitor::VisitExternalAsciiString(
4898 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4899}
4900
4901
4902void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4903 typedef v8::String::ExternalStringResource Resource;
4904 v->VisitExternalTwoByteString(
4905 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4906}
4907
4908
4909template<typename StaticVisitor>
4910void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4911 typedef v8::String::ExternalStringResource Resource;
4912 StaticVisitor::VisitExternalTwoByteString(
4913 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4914}
4915
4916#define SLOT_ADDR(obj, offset) \
4917 reinterpret_cast<Object**>((obj)->address() + offset)
4918
4919template<int start_offset, int end_offset, int size>
4920void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4921 HeapObject* obj,
4922 ObjectVisitor* v) {
4923 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4924}
4925
4926
4927template<int start_offset>
4928void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4929 int object_size,
4930 ObjectVisitor* v) {
4931 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4932}
4933
4934#undef SLOT_ADDR
4935
4936
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004937#undef CAST_ACCESSOR
4938#undef INT_ACCESSORS
4939#undef SMI_ACCESSORS
4940#undef ACCESSORS
4941#undef FIELD_ADDR
4942#undef READ_FIELD
4943#undef WRITE_FIELD
4944#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004945#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004946#undef READ_MEMADDR_FIELD
4947#undef WRITE_MEMADDR_FIELD
4948#undef READ_DOUBLE_FIELD
4949#undef WRITE_DOUBLE_FIELD
4950#undef READ_INT_FIELD
4951#undef WRITE_INT_FIELD
4952#undef READ_SHORT_FIELD
4953#undef WRITE_SHORT_FIELD
4954#undef READ_BYTE_FIELD
4955#undef WRITE_BYTE_FIELD
4956
4957
4958} } // namespace v8::internal
4959
4960#endif // V8_OBJECTS_INL_H_