blob: c5cf060829f5867cbfea4dc35d56a0c682e4a486 [file] [log] [blame]
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001// Copyright 2011 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27//
28// Review notes:
29//
ager@chromium.org32912102009-01-16 10:38:43 +000030// - The use of macros in these inline functions may seem superfluous
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000031// but it is absolutely needed to make sure gcc generates optimal
32// code. gcc is not happy when attempting to inline too deep.
33//
34
35#ifndef V8_OBJECTS_INL_H_
36#define V8_OBJECTS_INL_H_
37
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +000038#include "elements.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000039#include "objects.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000040#include "contexts.h"
41#include "conversions-inl.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000042#include "heap.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000043#include "isolate.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000044#include "property.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000045#include "spaces.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000046#include "store-buffer.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000047#include "v8memory.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000048
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000049#include "incremental-marking.h"
50
kasperl@chromium.org71affb52009-05-26 05:44:31 +000051namespace v8 {
52namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000053
54PropertyDetails::PropertyDetails(Smi* smi) {
55 value_ = smi->value();
56}
57
58
59Smi* PropertyDetails::AsSmi() {
60 return Smi::FromInt(value_);
61}
62
63
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000064PropertyDetails PropertyDetails::AsDeleted() {
ager@chromium.org378b34e2011-01-28 08:04:38 +000065 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000066 return PropertyDetails(smi);
67}
68
69
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +000070#define TYPE_CHECKER(type, instancetype) \
71 bool Object::Is##type() { \
72 return Object::IsHeapObject() && \
73 HeapObject::cast(this)->map()->instance_type() == instancetype; \
74 }
75
76
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000077#define CAST_ACCESSOR(type) \
78 type* type::cast(Object* object) { \
79 ASSERT(object->Is##type()); \
80 return reinterpret_cast<type*>(object); \
81 }
82
83
84#define INT_ACCESSORS(holder, name, offset) \
85 int holder::name() { return READ_INT_FIELD(this, offset); } \
86 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
87
88
89#define ACCESSORS(holder, name, type, offset) \
90 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000091 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000092 WRITE_FIELD(this, offset, value); \
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000093 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000094 }
95
96
97#define SMI_ACCESSORS(holder, name, offset) \
98 int holder::name() { \
99 Object* value = READ_FIELD(this, offset); \
100 return Smi::cast(value)->value(); \
101 } \
102 void holder::set_##name(int value) { \
103 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
104 }
105
106
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000107#define BOOL_GETTER(holder, field, name, offset) \
108 bool holder::name() { \
109 return BooleanBit::get(field(), offset); \
110 } \
111
112
113#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000114 bool holder::name() { \
115 return BooleanBit::get(field(), offset); \
116 } \
117 void holder::set_##name(bool value) { \
118 set_##field(BooleanBit::set(field(), offset, value)); \
119 }
120
121
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +0000122bool IsMoreGeneralElementsKindTransition(ElementsKind from_kind,
123 ElementsKind to_kind) {
124 if (to_kind == FAST_ELEMENTS) {
125 return from_kind == FAST_SMI_ONLY_ELEMENTS ||
126 from_kind == FAST_DOUBLE_ELEMENTS;
127 } else {
128 return to_kind == FAST_DOUBLE_ELEMENTS &&
129 from_kind == FAST_SMI_ONLY_ELEMENTS;
130 }
131}
132
133
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000134bool Object::IsFixedArrayBase() {
135 return IsFixedArray() || IsFixedDoubleArray();
136}
137
138
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000139bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
140 // There is a constraint on the object; check.
141 if (!this->IsJSObject()) return false;
142 // Fetch the constructor function of the object.
143 Object* cons_obj = JSObject::cast(this)->map()->constructor();
144 if (!cons_obj->IsJSFunction()) return false;
145 JSFunction* fun = JSFunction::cast(cons_obj);
146 // Iterate through the chain of inheriting function templates to
147 // see if the required one occurs.
148 for (Object* type = fun->shared()->function_data();
149 type->IsFunctionTemplateInfo();
150 type = FunctionTemplateInfo::cast(type)->parent_template()) {
151 if (type == expected) return true;
152 }
153 // Didn't find the required type in the inheritance chain.
154 return false;
155}
156
157
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000158bool Object::IsSmi() {
159 return HAS_SMI_TAG(this);
160}
161
162
163bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000164 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000165}
166
167
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000168bool Object::NonFailureIsHeapObject() {
169 ASSERT(!this->IsFailure());
170 return (reinterpret_cast<intptr_t>(this) & kSmiTagMask) != 0;
171}
172
173
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000174TYPE_CHECKER(HeapNumber, HEAP_NUMBER_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000175
176
177bool Object::IsString() {
178 return Object::IsHeapObject()
179 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
180}
181
182
ricow@chromium.org9fa09672011-07-25 11:05:35 +0000183bool Object::IsSpecObject() {
184 return Object::IsHeapObject()
185 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
186}
187
188
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000189bool Object::IsSpecFunction() {
190 if (!Object::IsHeapObject()) return false;
191 InstanceType type = HeapObject::cast(this)->map()->instance_type();
192 return type == JS_FUNCTION_TYPE || type == JS_FUNCTION_PROXY_TYPE;
193}
194
195
ager@chromium.org870a0b62008-11-04 11:43:05 +0000196bool Object::IsSymbol() {
197 if (!this->IsHeapObject()) return false;
198 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000199 // Because the symbol tag is non-zero and no non-string types have the
200 // symbol bit set we can test for symbols with a very simple test
201 // operation.
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000202 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000203 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
204 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000205}
206
207
208bool Object::IsConsString() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000209 if (!IsString()) return false;
210 return StringShape(String::cast(this)).IsCons();
211}
212
213
214bool Object::IsSlicedString() {
215 if (!IsString()) return false;
216 return StringShape(String::cast(this)).IsSliced();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000217}
218
219
ager@chromium.org870a0b62008-11-04 11:43:05 +0000220bool Object::IsSeqString() {
221 if (!IsString()) return false;
222 return StringShape(String::cast(this)).IsSequential();
223}
224
225
226bool Object::IsSeqAsciiString() {
227 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000228 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000229 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000230}
231
232
233bool Object::IsSeqTwoByteString() {
234 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000235 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000236 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000237}
238
239
240bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000241 if (!IsString()) return false;
242 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000243}
244
245
246bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000247 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000248 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000249 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000250}
251
252
253bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000254 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000255 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000256 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000257}
258
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000259bool Object::HasValidElements() {
260 // Dictionary is covered under FixedArray.
261 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
262}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000263
ager@chromium.org870a0b62008-11-04 11:43:05 +0000264StringShape::StringShape(String* str)
265 : type_(str->map()->instance_type()) {
266 set_valid();
267 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000268}
269
270
ager@chromium.org870a0b62008-11-04 11:43:05 +0000271StringShape::StringShape(Map* map)
272 : type_(map->instance_type()) {
273 set_valid();
274 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000275}
276
277
ager@chromium.org870a0b62008-11-04 11:43:05 +0000278StringShape::StringShape(InstanceType t)
279 : type_(static_cast<uint32_t>(t)) {
280 set_valid();
281 ASSERT((type_ & kIsNotStringMask) == kStringTag);
282}
283
284
285bool StringShape::IsSymbol() {
286 ASSERT(valid());
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000287 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000288 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000289}
290
291
ager@chromium.org5ec48922009-05-05 07:25:34 +0000292bool String::IsAsciiRepresentation() {
293 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000294 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000295}
296
297
ager@chromium.org5ec48922009-05-05 07:25:34 +0000298bool String::IsTwoByteRepresentation() {
299 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000300 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000301}
302
303
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000304bool String::IsAsciiRepresentationUnderneath() {
305 uint32_t type = map()->instance_type();
306 STATIC_ASSERT(kIsIndirectStringTag != 0);
307 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
308 ASSERT(IsFlat());
309 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
310 case kAsciiStringTag:
311 return true;
312 case kTwoByteStringTag:
313 return false;
314 default: // Cons or sliced string. Need to go deeper.
315 return GetUnderlying()->IsAsciiRepresentation();
316 }
317}
318
319
320bool String::IsTwoByteRepresentationUnderneath() {
321 uint32_t type = map()->instance_type();
322 STATIC_ASSERT(kIsIndirectStringTag != 0);
323 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
324 ASSERT(IsFlat());
325 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
326 case kAsciiStringTag:
327 return false;
328 case kTwoByteStringTag:
329 return true;
330 default: // Cons or sliced string. Need to go deeper.
331 return GetUnderlying()->IsTwoByteRepresentation();
332 }
333}
334
335
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000336bool String::HasOnlyAsciiChars() {
337 uint32_t type = map()->instance_type();
338 return (type & kStringEncodingMask) == kAsciiStringTag ||
339 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000340}
341
342
ager@chromium.org870a0b62008-11-04 11:43:05 +0000343bool StringShape::IsCons() {
344 return (type_ & kStringRepresentationMask) == kConsStringTag;
345}
346
347
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000348bool StringShape::IsSliced() {
349 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
350}
351
352
353bool StringShape::IsIndirect() {
354 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
355}
356
357
ager@chromium.org870a0b62008-11-04 11:43:05 +0000358bool StringShape::IsExternal() {
359 return (type_ & kStringRepresentationMask) == kExternalStringTag;
360}
361
362
363bool StringShape::IsSequential() {
364 return (type_ & kStringRepresentationMask) == kSeqStringTag;
365}
366
367
368StringRepresentationTag StringShape::representation_tag() {
369 uint32_t tag = (type_ & kStringRepresentationMask);
370 return static_cast<StringRepresentationTag>(tag);
371}
372
373
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000374uint32_t StringShape::encoding_tag() {
375 return type_ & kStringEncodingMask;
376}
377
378
ager@chromium.org870a0b62008-11-04 11:43:05 +0000379uint32_t StringShape::full_representation_tag() {
380 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
381}
382
383
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000384STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
385 Internals::kFullStringRepresentationMask);
386
387
ager@chromium.org870a0b62008-11-04 11:43:05 +0000388bool StringShape::IsSequentialAscii() {
389 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
390}
391
392
393bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000394 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000395}
396
397
398bool StringShape::IsExternalAscii() {
399 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
400}
401
402
403bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000404 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000405}
406
407
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000408STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
409 Internals::kExternalTwoByteRepresentationTag);
410
411
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000412uc32 FlatStringReader::Get(int index) {
413 ASSERT(0 <= index && index <= length_);
414 if (is_ascii_) {
415 return static_cast<const byte*>(start_)[index];
416 } else {
417 return static_cast<const uc16*>(start_)[index];
418 }
419}
420
421
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000422bool Object::IsNumber() {
423 return IsSmi() || IsHeapNumber();
424}
425
426
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000427TYPE_CHECKER(ByteArray, BYTE_ARRAY_TYPE)
428TYPE_CHECKER(FreeSpace, FREE_SPACE_TYPE)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000429
430
431bool Object::IsFiller() {
432 if (!Object::IsHeapObject()) return false;
433 InstanceType instance_type = HeapObject::cast(this)->map()->instance_type();
434 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
435}
436
437
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000438TYPE_CHECKER(ExternalPixelArray, EXTERNAL_PIXEL_ARRAY_TYPE)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000439
440
ager@chromium.org3811b432009-10-28 14:53:37 +0000441bool Object::IsExternalArray() {
442 if (!Object::IsHeapObject())
443 return false;
444 InstanceType instance_type =
445 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000446 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
447 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000448}
449
450
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000451TYPE_CHECKER(ExternalByteArray, EXTERNAL_BYTE_ARRAY_TYPE)
452TYPE_CHECKER(ExternalUnsignedByteArray, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
453TYPE_CHECKER(ExternalShortArray, EXTERNAL_SHORT_ARRAY_TYPE)
454TYPE_CHECKER(ExternalUnsignedShortArray, EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
455TYPE_CHECKER(ExternalIntArray, EXTERNAL_INT_ARRAY_TYPE)
456TYPE_CHECKER(ExternalUnsignedIntArray, EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
457TYPE_CHECKER(ExternalFloatArray, EXTERNAL_FLOAT_ARRAY_TYPE)
458TYPE_CHECKER(ExternalDoubleArray, EXTERNAL_DOUBLE_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000459
460
lrn@chromium.org303ada72010-10-27 09:33:13 +0000461bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000462 return HAS_FAILURE_TAG(this);
463}
464
465
lrn@chromium.org303ada72010-10-27 09:33:13 +0000466bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000467 return HAS_FAILURE_TAG(this)
468 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
469}
470
471
lrn@chromium.org303ada72010-10-27 09:33:13 +0000472bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000473 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000474 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000475}
476
477
lrn@chromium.org303ada72010-10-27 09:33:13 +0000478bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000479 return this == Failure::Exception();
480}
481
482
lrn@chromium.org303ada72010-10-27 09:33:13 +0000483bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000484 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000485}
486
487
488Failure* Failure::cast(MaybeObject* obj) {
489 ASSERT(HAS_FAILURE_TAG(obj));
490 return reinterpret_cast<Failure*>(obj);
491}
492
493
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000494bool Object::IsJSReceiver() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000495 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000496 return IsHeapObject() &&
497 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
498}
499
500
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000501bool Object::IsJSObject() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000502 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
503 return IsHeapObject() &&
504 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000505}
506
507
508bool Object::IsJSProxy() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000509 if (!Object::IsHeapObject()) return false;
510 InstanceType type = HeapObject::cast(this)->map()->instance_type();
511 return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000512}
513
514
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000515TYPE_CHECKER(JSFunctionProxy, JS_FUNCTION_PROXY_TYPE)
516TYPE_CHECKER(JSSet, JS_SET_TYPE)
517TYPE_CHECKER(JSMap, JS_MAP_TYPE)
518TYPE_CHECKER(JSWeakMap, JS_WEAK_MAP_TYPE)
519TYPE_CHECKER(JSContextExtensionObject, JS_CONTEXT_EXTENSION_OBJECT_TYPE)
520TYPE_CHECKER(Map, MAP_TYPE)
521TYPE_CHECKER(FixedArray, FIXED_ARRAY_TYPE)
522TYPE_CHECKER(FixedDoubleArray, FIXED_DOUBLE_ARRAY_TYPE)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000523
524
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000525bool Object::IsDescriptorArray() {
526 return IsFixedArray();
527}
528
529
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000530bool Object::IsDeoptimizationInputData() {
531 // Must be a fixed array.
532 if (!IsFixedArray()) return false;
533
534 // There's no sure way to detect the difference between a fixed array and
535 // a deoptimization data array. Since this is used for asserts we can
536 // check that the length is zero or else the fixed size plus a multiple of
537 // the entry size.
538 int length = FixedArray::cast(this)->length();
539 if (length == 0) return true;
540
541 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
542 return length >= 0 &&
543 length % DeoptimizationInputData::kDeoptEntrySize == 0;
544}
545
546
547bool Object::IsDeoptimizationOutputData() {
548 if (!IsFixedArray()) return false;
549 // There's actually no way to see the difference between a fixed array and
550 // a deoptimization data array. Since this is used for asserts we can check
551 // that the length is plausible though.
552 if (FixedArray::cast(this)->length() % 2 != 0) return false;
553 return true;
554}
555
556
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000557bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000558 if (Object::IsHeapObject()) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000559 Map* map = HeapObject::cast(this)->map();
560 Heap* heap = map->GetHeap();
561 return (map == heap->function_context_map() ||
562 map == heap->catch_context_map() ||
563 map == heap->with_context_map() ||
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000564 map == heap->global_context_map() ||
565 map == heap->block_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000566 }
567 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000568}
569
570
571bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000572 return Object::IsHeapObject() &&
573 HeapObject::cast(this)->map() ==
574 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000575}
576
577
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000578bool Object::IsScopeInfo() {
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000579 return Object::IsHeapObject() &&
580 HeapObject::cast(this)->map() ==
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +0000581 HeapObject::cast(this)->GetHeap()->scope_info_map();
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000582}
583
584
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000585TYPE_CHECKER(JSFunction, JS_FUNCTION_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000586
587
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000588template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000589 return obj->IsJSFunction();
590}
591
592
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000593TYPE_CHECKER(Code, CODE_TYPE)
594TYPE_CHECKER(Oddball, ODDBALL_TYPE)
595TYPE_CHECKER(JSGlobalPropertyCell, JS_GLOBAL_PROPERTY_CELL_TYPE)
596TYPE_CHECKER(SharedFunctionInfo, SHARED_FUNCTION_INFO_TYPE)
597TYPE_CHECKER(JSValue, JS_VALUE_TYPE)
598TYPE_CHECKER(JSMessageObject, JS_MESSAGE_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000599
600
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000601bool Object::IsStringWrapper() {
602 return IsJSValue() && JSValue::cast(this)->value()->IsString();
603}
604
605
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000606TYPE_CHECKER(Foreign, FOREIGN_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000607
608
609bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000610 return IsOddball() &&
611 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000612}
613
614
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000615TYPE_CHECKER(JSArray, JS_ARRAY_TYPE)
616TYPE_CHECKER(JSRegExp, JS_REGEXP_TYPE)
ager@chromium.org236ad962008-09-25 09:45:57 +0000617
618
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000619template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000620 return obj->IsJSArray();
621}
622
623
624bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000625 return Object::IsHeapObject() &&
626 HeapObject::cast(this)->map() ==
627 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000628}
629
630
631bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000632 return IsHashTable() &&
633 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000634}
635
636
637bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000638 return IsHashTable() && this ==
639 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000640}
641
642
ager@chromium.orgac091b72010-05-05 07:34:42 +0000643bool Object::IsJSFunctionResultCache() {
644 if (!IsFixedArray()) return false;
645 FixedArray* self = FixedArray::cast(this);
646 int length = self->length();
647 if (length < JSFunctionResultCache::kEntriesIndex) return false;
648 if ((length - JSFunctionResultCache::kEntriesIndex)
649 % JSFunctionResultCache::kEntrySize != 0) {
650 return false;
651 }
652#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000653 if (FLAG_verify_heap) {
654 reinterpret_cast<JSFunctionResultCache*>(this)->
655 JSFunctionResultCacheVerify();
656 }
ager@chromium.orgac091b72010-05-05 07:34:42 +0000657#endif
658 return true;
659}
660
661
ricow@chromium.org65fae842010-08-25 15:26:24 +0000662bool Object::IsNormalizedMapCache() {
663 if (!IsFixedArray()) return false;
664 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
665 return false;
666 }
667#ifdef DEBUG
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000668 if (FLAG_verify_heap) {
669 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
670 }
ricow@chromium.org65fae842010-08-25 15:26:24 +0000671#endif
672 return true;
673}
674
675
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000676bool Object::IsCompilationCacheTable() {
677 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000678}
679
680
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000681bool Object::IsCodeCacheHashTable() {
682 return IsHashTable();
683}
684
685
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000686bool Object::IsPolymorphicCodeCacheHashTable() {
687 return IsHashTable();
688}
689
690
ager@chromium.org236ad962008-09-25 09:45:57 +0000691bool Object::IsMapCache() {
692 return IsHashTable();
693}
694
695
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000696bool Object::IsPrimitive() {
697 return IsOddball() || IsNumber() || IsString();
698}
699
700
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000701bool Object::IsJSGlobalProxy() {
702 bool result = IsHeapObject() &&
703 (HeapObject::cast(this)->map()->instance_type() ==
704 JS_GLOBAL_PROXY_TYPE);
705 ASSERT(!result || IsAccessCheckNeeded());
706 return result;
707}
708
709
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000710bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000711 if (!IsHeapObject()) return false;
712
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000713 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000714 return type == JS_GLOBAL_OBJECT_TYPE ||
715 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000716}
717
718
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +0000719TYPE_CHECKER(JSGlobalObject, JS_GLOBAL_OBJECT_TYPE)
720TYPE_CHECKER(JSBuiltinsObject, JS_BUILTINS_OBJECT_TYPE)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000721
722
723bool Object::IsUndetectableObject() {
724 return IsHeapObject()
725 && HeapObject::cast(this)->map()->is_undetectable();
726}
727
728
729bool Object::IsAccessCheckNeeded() {
730 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000731 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000732}
733
734
735bool Object::IsStruct() {
736 if (!IsHeapObject()) return false;
737 switch (HeapObject::cast(this)->map()->instance_type()) {
738#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
739 STRUCT_LIST(MAKE_STRUCT_CASE)
740#undef MAKE_STRUCT_CASE
741 default: return false;
742 }
743}
744
745
746#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
747 bool Object::Is##Name() { \
748 return Object::IsHeapObject() \
749 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
750 }
751 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
752#undef MAKE_STRUCT_PREDICATE
753
754
755bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000756 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000757}
758
759
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000760bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000761 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
762}
763
764
765bool Object::IsTheHole() {
766 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000767}
768
769
770bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000771 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000772}
773
774
775bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000776 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000777}
778
779
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000780bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000781 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000782}
783
784
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000785double Object::Number() {
786 ASSERT(IsNumber());
787 return IsSmi()
788 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
789 : reinterpret_cast<HeapNumber*>(this)->value();
790}
791
792
lrn@chromium.org303ada72010-10-27 09:33:13 +0000793MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000794 if (IsSmi()) return this;
795 if (IsHeapNumber()) {
796 double value = HeapNumber::cast(this)->value();
797 int int_value = FastD2I(value);
798 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
799 return Smi::FromInt(int_value);
800 }
801 }
802 return Failure::Exception();
803}
804
805
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000806bool Object::HasSpecificClassOf(String* name) {
807 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
808}
809
810
lrn@chromium.org303ada72010-10-27 09:33:13 +0000811MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000812 // GetElement can trigger a getter which can cause allocation.
813 // This was not always the case. This ASSERT is here to catch
814 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000815 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000816 return GetElementWithReceiver(this, index);
817}
818
819
lrn@chromium.org303ada72010-10-27 09:33:13 +0000820Object* Object::GetElementNoExceptionThrown(uint32_t index) {
821 MaybeObject* maybe = GetElementWithReceiver(this, index);
822 ASSERT(!maybe->IsFailure());
823 Object* result = NULL; // Initialization to please compiler.
824 maybe->ToObject(&result);
825 return result;
826}
827
828
829MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000830 PropertyAttributes attributes;
831 return GetPropertyWithReceiver(this, key, &attributes);
832}
833
834
lrn@chromium.org303ada72010-10-27 09:33:13 +0000835MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000836 return GetPropertyWithReceiver(this, key, attributes);
837}
838
839
840#define FIELD_ADDR(p, offset) \
841 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
842
843#define READ_FIELD(p, offset) \
844 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
845
846#define WRITE_FIELD(p, offset, value) \
847 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
848
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000849#define WRITE_BARRIER(heap, object, offset, value) \
850 heap->incremental_marking()->RecordWrite( \
851 object, HeapObject::RawField(object, offset), value); \
852 if (heap->InNewSpace(value)) { \
853 heap->RecordWrite(object->address(), offset); \
854 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000855
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000856#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
857 if (mode == UPDATE_WRITE_BARRIER) { \
858 heap->incremental_marking()->RecordWrite( \
859 object, HeapObject::RawField(object, offset), value); \
860 if (heap->InNewSpace(value)) { \
861 heap->RecordWrite(object->address(), offset); \
862 } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000863 }
864
lrn@chromium.org7516f052011-03-30 08:52:27 +0000865#ifndef V8_TARGET_ARCH_MIPS
866 #define READ_DOUBLE_FIELD(p, offset) \
867 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
868#else // V8_TARGET_ARCH_MIPS
869 // Prevent gcc from using load-double (mips ldc1) on (possibly)
870 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000871 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000872 union conversion {
873 double d;
874 uint32_t u[2];
875 } c;
876 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
877 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
878 return c.d;
879 }
880 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
881#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000882
lrn@chromium.org7516f052011-03-30 08:52:27 +0000883#ifndef V8_TARGET_ARCH_MIPS
884 #define WRITE_DOUBLE_FIELD(p, offset, value) \
885 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
886#else // V8_TARGET_ARCH_MIPS
887 // Prevent gcc from using store-double (mips sdc1) on (possibly)
888 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000889 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000890 double value) {
891 union conversion {
892 double d;
893 uint32_t u[2];
894 } c;
895 c.d = value;
896 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
897 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
898 }
899 #define WRITE_DOUBLE_FIELD(p, offset, value) \
900 write_double_field(p, offset, value)
901#endif // V8_TARGET_ARCH_MIPS
902
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000903
904#define READ_INT_FIELD(p, offset) \
905 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
906
907#define WRITE_INT_FIELD(p, offset, value) \
908 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
909
ager@chromium.org3e875802009-06-29 08:26:34 +0000910#define READ_INTPTR_FIELD(p, offset) \
911 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
912
913#define WRITE_INTPTR_FIELD(p, offset, value) \
914 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
915
ager@chromium.org7c537e22008-10-16 08:43:32 +0000916#define READ_UINT32_FIELD(p, offset) \
917 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
918
919#define WRITE_UINT32_FIELD(p, offset, value) \
920 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
921
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000922#define READ_SHORT_FIELD(p, offset) \
923 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
924
925#define WRITE_SHORT_FIELD(p, offset, value) \
926 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
927
928#define READ_BYTE_FIELD(p, offset) \
929 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
930
931#define WRITE_BYTE_FIELD(p, offset, value) \
932 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
933
934
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000935Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
936 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000937}
938
939
940int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000941 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000942}
943
944
945Smi* Smi::FromInt(int value) {
946 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000947 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000948 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000949 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000950 return reinterpret_cast<Smi*>(tagged_value);
951}
952
953
954Smi* Smi::FromIntptr(intptr_t value) {
955 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000956 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
957 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000958}
959
960
961Failure::Type Failure::type() const {
962 return static_cast<Type>(value() & kFailureTypeTagMask);
963}
964
965
966bool Failure::IsInternalError() const {
967 return type() == INTERNAL_ERROR;
968}
969
970
971bool Failure::IsOutOfMemoryException() const {
972 return type() == OUT_OF_MEMORY_EXCEPTION;
973}
974
975
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000976AllocationSpace Failure::allocation_space() const {
977 ASSERT_EQ(RETRY_AFTER_GC, type());
978 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
979 & kSpaceTagMask);
980}
981
982
983Failure* Failure::InternalError() {
984 return Construct(INTERNAL_ERROR);
985}
986
987
988Failure* Failure::Exception() {
989 return Construct(EXCEPTION);
990}
991
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000992
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000993Failure* Failure::OutOfMemoryException() {
994 return Construct(OUT_OF_MEMORY_EXCEPTION);
995}
996
997
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000998intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000999 return static_cast<intptr_t>(
1000 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001001}
1002
1003
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001004Failure* Failure::RetryAfterGC() {
1005 return RetryAfterGC(NEW_SPACE);
1006}
1007
1008
1009Failure* Failure::RetryAfterGC(AllocationSpace space) {
1010 ASSERT((space & ~kSpaceTagMask) == 0);
1011 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001012}
1013
1014
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001015Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001016 uintptr_t info =
1017 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001018 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001019 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001020}
1021
1022
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001023bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001024#ifdef DEBUG
1025 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1026#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001027
1028#ifdef V8_TARGET_ARCH_X64
1029 // To be representable as a long smi, the value must be a 32-bit integer.
1030 bool result = (value == static_cast<int32_t>(value));
1031#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001032 // To be representable as an tagged small integer, the two
1033 // most-significant bits of 'value' must be either 00 or 11 due to
1034 // sign-extension. To check this we add 01 to the two
1035 // most-significant bits, and check if the most-significant bit is 0
1036 //
1037 // CAUTION: The original code below:
1038 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1039 // may lead to incorrect results according to the C language spec, and
1040 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1041 // compiler may produce undefined results in case of signed integer
1042 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001043 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001044#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001045 ASSERT(result == in_range);
1046 return result;
1047}
1048
1049
kasper.lund7276f142008-07-30 08:49:36 +00001050MapWord MapWord::FromMap(Map* map) {
1051 return MapWord(reinterpret_cast<uintptr_t>(map));
1052}
1053
1054
1055Map* MapWord::ToMap() {
1056 return reinterpret_cast<Map*>(value_);
1057}
1058
1059
1060bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001061 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001062}
1063
1064
1065MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001066 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1067 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001068}
1069
1070
1071HeapObject* MapWord::ToForwardingAddress() {
1072 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001073 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001074}
1075
1076
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001077#ifdef DEBUG
1078void HeapObject::VerifyObjectField(int offset) {
1079 VerifyPointer(READ_FIELD(this, offset));
1080}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001081
1082void HeapObject::VerifySmiField(int offset) {
1083 ASSERT(READ_FIELD(this, offset)->IsSmi());
1084}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001085#endif
1086
1087
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001088Heap* HeapObject::GetHeap() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001089 Heap* heap =
1090 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1091 ASSERT(heap != NULL);
1092 ASSERT(heap->isolate() == Isolate::Current());
1093 return heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001094}
1095
1096
1097Isolate* HeapObject::GetIsolate() {
1098 return GetHeap()->isolate();
1099}
1100
1101
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001102Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001103 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001104}
1105
1106
1107void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001108 set_map_word(MapWord::FromMap(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001109 if (value != NULL) {
1110 // TODO(1600) We are passing NULL as a slot because maps can never be on
1111 // evacuation candidate.
1112 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1113 }
1114}
1115
1116
1117// Unsafe accessor omitting write barrier.
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001118void HeapObject::set_map_no_write_barrier(Map* value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001119 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001120}
1121
1122
kasper.lund7276f142008-07-30 08:49:36 +00001123MapWord HeapObject::map_word() {
1124 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1125}
1126
1127
1128void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001129 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001130 // here.
1131 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1132}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001133
1134
1135HeapObject* HeapObject::FromAddress(Address address) {
1136 ASSERT_TAG_ALIGNED(address);
1137 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1138}
1139
1140
1141Address HeapObject::address() {
1142 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1143}
1144
1145
1146int HeapObject::Size() {
1147 return SizeFromMap(map());
1148}
1149
1150
1151void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1152 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1153 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1154}
1155
1156
1157void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1158 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1159}
1160
1161
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001162double HeapNumber::value() {
1163 return READ_DOUBLE_FIELD(this, kValueOffset);
1164}
1165
1166
1167void HeapNumber::set_value(double value) {
1168 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1169}
1170
1171
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001172int HeapNumber::get_exponent() {
1173 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1174 kExponentShift) - kExponentBias;
1175}
1176
1177
1178int HeapNumber::get_sign() {
1179 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1180}
1181
1182
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001183ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001184
1185
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001186Object** FixedArray::GetFirstElementAddress() {
1187 return reinterpret_cast<Object**>(FIELD_ADDR(this, OffsetOfElementAt(0)));
1188}
1189
1190
1191bool FixedArray::ContainsOnlySmisOrHoles() {
1192 Object* the_hole = GetHeap()->the_hole_value();
1193 Object** current = GetFirstElementAddress();
1194 for (int i = 0; i < length(); ++i) {
1195 Object* candidate = *current++;
1196 if (!candidate->IsSmi() && candidate != the_hole) return false;
1197 }
1198 return true;
1199}
1200
1201
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001202FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001203 Object* array = READ_FIELD(this, kElementsOffset);
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001204 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001205}
1206
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001207void JSObject::ValidateSmiOnlyElements() {
1208#if DEBUG
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001209 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001210 Heap* heap = GetHeap();
1211 // Don't use elements, since integrity checks will fail if there
1212 // are filler pointers in the array.
1213 FixedArray* fixed_array =
1214 reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset));
1215 Map* map = fixed_array->map();
1216 // Arrays that have been shifted in place can't be verified.
1217 if (map != heap->raw_unchecked_one_pointer_filler_map() &&
1218 map != heap->raw_unchecked_two_pointer_filler_map() &&
1219 map != heap->free_space_map()) {
1220 for (int i = 0; i < fixed_array->length(); i++) {
1221 Object* current = fixed_array->get(i);
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001222 ASSERT(current->IsSmi() || current->IsTheHole());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001223 }
1224 }
1225 }
1226#endif
1227}
1228
1229
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001230MaybeObject* JSObject::EnsureCanContainHeapObjectElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001231#if DEBUG
1232 ValidateSmiOnlyElements();
1233#endif
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001234 if ((map()->elements_kind() != FAST_ELEMENTS)) {
1235 return TransitionElementsKind(FAST_ELEMENTS);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001236 }
1237 return this;
1238}
1239
1240
1241MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001242 uint32_t count,
1243 EnsureElementsMode mode) {
1244 ElementsKind current_kind = map()->elements_kind();
1245 ElementsKind target_kind = current_kind;
1246 ASSERT(mode != ALLOW_COPIED_DOUBLE_ELEMENTS);
1247 if (current_kind == FAST_ELEMENTS) return this;
1248
1249 Heap* heap = GetHeap();
1250 Object* the_hole = heap->the_hole_value();
1251 Object* heap_number_map = heap->heap_number_map();
1252 for (uint32_t i = 0; i < count; ++i) {
1253 Object* current = *objects++;
1254 if (!current->IsSmi() && current != the_hole) {
1255 if (mode == ALLOW_CONVERTED_DOUBLE_ELEMENTS &&
1256 HeapObject::cast(current)->map() == heap_number_map) {
1257 target_kind = FAST_DOUBLE_ELEMENTS;
1258 } else {
1259 target_kind = FAST_ELEMENTS;
1260 break;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001261 }
1262 }
1263 }
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001264
1265 if (target_kind != current_kind) {
1266 return TransitionElementsKind(target_kind);
1267 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001268 return this;
1269}
1270
1271
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001272MaybeObject* JSObject::EnsureCanContainElements(FixedArrayBase* elements,
1273 EnsureElementsMode mode) {
1274 if (elements->map() != GetHeap()->fixed_double_array_map()) {
1275 ASSERT(elements->map() == GetHeap()->fixed_array_map() ||
1276 elements->map() == GetHeap()->fixed_cow_array_map());
1277 if (mode == ALLOW_COPIED_DOUBLE_ELEMENTS) {
1278 mode = DONT_ALLOW_DOUBLE_ELEMENTS;
1279 }
1280 Object** objects = FixedArray::cast(elements)->GetFirstElementAddress();
1281 return EnsureCanContainElements(objects, elements->length(), mode);
1282 }
1283
1284 ASSERT(mode == ALLOW_COPIED_DOUBLE_ELEMENTS);
1285 if (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS) {
1286 return TransitionElementsKind(FAST_DOUBLE_ELEMENTS);
1287 }
1288
1289 return this;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001290}
1291
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001292
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001293void JSObject::set_map_and_elements(Map* new_map,
1294 FixedArrayBase* value,
1295 WriteBarrierMode mode) {
1296 ASSERT(value->HasValidElements());
1297#ifdef DEBUG
1298 ValidateSmiOnlyElements();
1299#endif
1300 if (new_map != NULL) {
1301 if (mode == UPDATE_WRITE_BARRIER) {
1302 set_map(new_map);
1303 } else {
1304 ASSERT(mode == SKIP_WRITE_BARRIER);
1305 set_map_no_write_barrier(new_map);
1306 }
1307 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001308 ASSERT((map()->has_fast_elements() ||
1309 map()->has_fast_smi_only_elements()) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001310 (value->map() == GetHeap()->fixed_array_map() ||
1311 value->map() == GetHeap()->fixed_cow_array_map()));
lrn@chromium.orgd4e9e222011-08-03 12:01:58 +00001312 ASSERT(map()->has_fast_double_elements() ==
1313 value->IsFixedDoubleArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001314 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001315 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001316}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001317
1318
svenpanne@chromium.org3c93e772012-01-02 09:26:59 +00001319void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
1320 set_map_and_elements(NULL, value, mode);
1321}
1322
1323
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001324void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001325 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1326 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001327}
1328
1329
1330void JSObject::initialize_elements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001331 ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001332 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1333 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001334}
1335
1336
lrn@chromium.org303ada72010-10-27 09:33:13 +00001337MaybeObject* JSObject::ResetElements() {
1338 Object* obj;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001339 ElementsKind elements_kind = FLAG_smi_only_arrays
1340 ? FAST_SMI_ONLY_ELEMENTS
1341 : FAST_ELEMENTS;
1342 MaybeObject* maybe_obj = GetElementsTransitionMap(elements_kind);
1343 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001344 set_map(Map::cast(obj));
1345 initialize_elements();
1346 return this;
1347}
1348
1349
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001350ACCESSORS(Oddball, to_string, String, kToStringOffset)
1351ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1352
1353
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001354byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001355 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001356}
1357
1358
1359void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001360 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001361}
1362
1363
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001364Object* JSGlobalPropertyCell::value() {
1365 return READ_FIELD(this, kValueOffset);
1366}
1367
1368
1369void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1370 // The write barrier is not used for global property cells.
1371 ASSERT(!val->IsJSGlobalPropertyCell());
1372 WRITE_FIELD(this, kValueOffset, val);
1373}
1374
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001375
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001376int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001377 InstanceType type = map()->instance_type();
1378 // Check for the most common kind of JavaScript object before
1379 // falling into the generic switch. This speeds up the internal
1380 // field operations considerably on average.
1381 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1382 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001383 case JS_GLOBAL_PROXY_TYPE:
1384 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001385 case JS_GLOBAL_OBJECT_TYPE:
1386 return JSGlobalObject::kSize;
1387 case JS_BUILTINS_OBJECT_TYPE:
1388 return JSBuiltinsObject::kSize;
1389 case JS_FUNCTION_TYPE:
1390 return JSFunction::kSize;
1391 case JS_VALUE_TYPE:
1392 return JSValue::kSize;
1393 case JS_ARRAY_TYPE:
1394 return JSValue::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001395 case JS_WEAK_MAP_TYPE:
1396 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001397 case JS_REGEXP_TYPE:
1398 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001399 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001400 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001401 case JS_MESSAGE_OBJECT_TYPE:
1402 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001403 default:
1404 UNREACHABLE();
1405 return 0;
1406 }
1407}
1408
1409
1410int JSObject::GetInternalFieldCount() {
1411 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001412 // Make sure to adjust for the number of in-object properties. These
1413 // properties do contribute to the size, but are not internal fields.
1414 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1415 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001416}
1417
1418
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001419int JSObject::GetInternalFieldOffset(int index) {
1420 ASSERT(index < GetInternalFieldCount() && index >= 0);
1421 return GetHeaderSize() + (kPointerSize * index);
1422}
1423
1424
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001425Object* JSObject::GetInternalField(int index) {
1426 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001427 // Internal objects do follow immediately after the header, whereas in-object
1428 // properties are at the end of the object. Therefore there is no need
1429 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001430 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1431}
1432
1433
1434void JSObject::SetInternalField(int index, Object* value) {
1435 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001436 // Internal objects do follow immediately after the header, whereas in-object
1437 // properties are at the end of the object. Therefore there is no need
1438 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001439 int offset = GetHeaderSize() + (kPointerSize * index);
1440 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001441 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001442}
1443
1444
ricow@chromium.org27bf2882011-11-17 08:34:43 +00001445void JSObject::SetInternalField(int index, Smi* value) {
1446 ASSERT(index < GetInternalFieldCount() && index >= 0);
1447 // Internal objects do follow immediately after the header, whereas in-object
1448 // properties are at the end of the object. Therefore there is no need
1449 // to adjust the index here.
1450 int offset = GetHeaderSize() + (kPointerSize * index);
1451 WRITE_FIELD(this, offset, value);
1452}
1453
1454
ager@chromium.org7c537e22008-10-16 08:43:32 +00001455// Access fast-case object properties at index. The use of these routines
1456// is needed to correctly distinguish between properties stored in-object and
1457// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001458Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001459 // Adjust for the number of properties stored in the object.
1460 index -= map()->inobject_properties();
1461 if (index < 0) {
1462 int offset = map()->instance_size() + (index * kPointerSize);
1463 return READ_FIELD(this, offset);
1464 } else {
1465 ASSERT(index < properties()->length());
1466 return properties()->get(index);
1467 }
1468}
1469
1470
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001471Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001472 // Adjust for the number of properties stored in the object.
1473 index -= map()->inobject_properties();
1474 if (index < 0) {
1475 int offset = map()->instance_size() + (index * kPointerSize);
1476 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001477 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001478 } else {
1479 ASSERT(index < properties()->length());
1480 properties()->set(index, value);
1481 }
1482 return value;
1483}
1484
1485
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001486int JSObject::GetInObjectPropertyOffset(int index) {
1487 // Adjust for the number of properties stored in the object.
1488 index -= map()->inobject_properties();
1489 ASSERT(index < 0);
1490 return map()->instance_size() + (index * kPointerSize);
1491}
1492
1493
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001494Object* JSObject::InObjectPropertyAt(int index) {
1495 // Adjust for the number of properties stored in the object.
1496 index -= map()->inobject_properties();
1497 ASSERT(index < 0);
1498 int offset = map()->instance_size() + (index * kPointerSize);
1499 return READ_FIELD(this, offset);
1500}
1501
1502
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001503Object* JSObject::InObjectPropertyAtPut(int index,
1504 Object* value,
1505 WriteBarrierMode mode) {
1506 // Adjust for the number of properties stored in the object.
1507 index -= map()->inobject_properties();
1508 ASSERT(index < 0);
1509 int offset = map()->instance_size() + (index * kPointerSize);
1510 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001511 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001512 return value;
1513}
1514
1515
1516
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001517void JSObject::InitializeBody(Map* map,
1518 Object* pre_allocated_value,
1519 Object* filler_value) {
1520 ASSERT(!filler_value->IsHeapObject() ||
1521 !GetHeap()->InNewSpace(filler_value));
1522 ASSERT(!pre_allocated_value->IsHeapObject() ||
1523 !GetHeap()->InNewSpace(pre_allocated_value));
1524 int size = map->instance_size();
1525 int offset = kHeaderSize;
1526 if (filler_value != pre_allocated_value) {
1527 int pre_allocated = map->pre_allocated_property_fields();
1528 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1529 for (int i = 0; i < pre_allocated; i++) {
1530 WRITE_FIELD(this, offset, pre_allocated_value);
1531 offset += kPointerSize;
1532 }
1533 }
1534 while (offset < size) {
1535 WRITE_FIELD(this, offset, filler_value);
1536 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001537 }
1538}
1539
1540
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001541bool JSObject::HasFastProperties() {
1542 return !properties()->IsDictionary();
1543}
1544
1545
1546int JSObject::MaxFastProperties() {
1547 // Allow extra fast properties if the object has more than
1548 // kMaxFastProperties in-object properties. When this is the case,
1549 // it is very unlikely that the object is being used as a dictionary
1550 // and there is a good chance that allowing more map transitions
1551 // will be worth it.
1552 return Max(map()->inobject_properties(), kMaxFastProperties);
1553}
1554
1555
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001556void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001557 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001558 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001559 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001560 }
1561}
1562
1563
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001564bool Object::ToArrayIndex(uint32_t* index) {
1565 if (IsSmi()) {
1566 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001567 if (value < 0) return false;
1568 *index = value;
1569 return true;
1570 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001571 if (IsHeapNumber()) {
1572 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001573 uint32_t uint_value = static_cast<uint32_t>(value);
1574 if (value == static_cast<double>(uint_value)) {
1575 *index = uint_value;
1576 return true;
1577 }
1578 }
1579 return false;
1580}
1581
1582
1583bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1584 if (!this->IsJSValue()) return false;
1585
1586 JSValue* js_value = JSValue::cast(this);
1587 if (!js_value->value()->IsString()) return false;
1588
1589 String* str = String::cast(js_value->value());
1590 if (index >= (uint32_t)str->length()) return false;
1591
1592 return true;
1593}
1594
1595
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001596FixedArrayBase* FixedArrayBase::cast(Object* object) {
1597 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1598 return reinterpret_cast<FixedArrayBase*>(object);
1599}
1600
1601
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001602Object* FixedArray::get(int index) {
1603 ASSERT(index >= 0 && index < this->length());
1604 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1605}
1606
1607
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001608void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001609 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001610 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001611 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1612 int offset = kHeaderSize + index * kPointerSize;
1613 WRITE_FIELD(this, offset, value);
1614}
1615
1616
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001617void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001618 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001619 ASSERT(index >= 0 && index < this->length());
1620 int offset = kHeaderSize + index * kPointerSize;
1621 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001622 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001623}
1624
1625
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001626inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1627 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1628}
1629
1630
1631inline double FixedDoubleArray::hole_nan_as_double() {
1632 return BitCast<double, uint64_t>(kHoleNanInt64);
1633}
1634
1635
1636inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1637 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1638 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1639 return OS::nan_value();
1640}
1641
1642
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001643double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001644 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1645 map() != HEAP->fixed_array_map());
1646 ASSERT(index >= 0 && index < this->length());
1647 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1648 ASSERT(!is_the_hole_nan(result));
1649 return result;
1650}
1651
1652
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001653MaybeObject* FixedDoubleArray::get(int index) {
1654 if (is_the_hole(index)) {
1655 return GetHeap()->the_hole_value();
1656 } else {
1657 return GetHeap()->NumberFromDouble(get_scalar(index));
1658 }
1659}
1660
1661
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001662void FixedDoubleArray::set(int index, double value) {
1663 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1664 map() != HEAP->fixed_array_map());
1665 int offset = kHeaderSize + index * kDoubleSize;
1666 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1667 WRITE_DOUBLE_FIELD(this, offset, value);
1668}
1669
1670
1671void FixedDoubleArray::set_the_hole(int index) {
1672 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1673 map() != HEAP->fixed_array_map());
1674 int offset = kHeaderSize + index * kDoubleSize;
1675 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1676}
1677
1678
1679bool FixedDoubleArray::is_the_hole(int index) {
1680 int offset = kHeaderSize + index * kDoubleSize;
1681 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1682}
1683
1684
1685void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1686 int old_length = from->length();
1687 ASSERT(old_length < length());
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001688 if (old_length * kDoubleSize >= OS::kMinComplexMemCopy) {
1689 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1690 FIELD_ADDR(from, kHeaderSize),
1691 old_length * kDoubleSize);
1692 } else {
1693 for (int i = 0; i < old_length; ++i) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001694 if (from->is_the_hole(i)) {
1695 set_the_hole(i);
1696 } else {
1697 set(i, from->get_scalar(i));
1698 }
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001699 }
1700 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001701 int offset = kHeaderSize + old_length * kDoubleSize;
1702 for (int current = from->length(); current < length(); ++current) {
1703 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1704 offset += kDoubleSize;
1705 }
1706}
1707
1708
1709void FixedDoubleArray::Initialize(FixedArray* from) {
1710 int old_length = from->length();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001711 ASSERT(old_length <= length());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001712 for (int i = 0; i < old_length; i++) {
1713 Object* hole_or_object = from->get(i);
1714 if (hole_or_object->IsTheHole()) {
1715 set_the_hole(i);
1716 } else {
1717 set(i, hole_or_object->Number());
1718 }
1719 }
1720 int offset = kHeaderSize + old_length * kDoubleSize;
1721 for (int current = from->length(); current < length(); ++current) {
1722 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1723 offset += kDoubleSize;
1724 }
1725}
1726
1727
1728void FixedDoubleArray::Initialize(NumberDictionary* from) {
1729 int offset = kHeaderSize;
1730 for (int current = 0; current < length(); ++current) {
1731 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1732 offset += kDoubleSize;
1733 }
1734 for (int i = 0; i < from->Capacity(); i++) {
1735 Object* key = from->KeyAt(i);
1736 if (key->IsNumber()) {
1737 uint32_t entry = static_cast<uint32_t>(key->Number());
1738 set(entry, from->ValueAt(i)->Number());
1739 }
1740 }
1741}
1742
1743
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001744WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001745 Heap* heap = GetHeap();
1746 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1747 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001748 return UPDATE_WRITE_BARRIER;
1749}
1750
1751
1752void FixedArray::set(int index,
1753 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001754 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001755 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001756 ASSERT(index >= 0 && index < this->length());
1757 int offset = kHeaderSize + index * kPointerSize;
1758 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001759 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001760}
1761
1762
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001763void FixedArray::NoIncrementalWriteBarrierSet(FixedArray* array,
1764 int index,
1765 Object* value) {
1766 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
1767 ASSERT(index >= 0 && index < array->length());
1768 int offset = kHeaderSize + index * kPointerSize;
1769 WRITE_FIELD(array, offset, value);
1770 Heap* heap = array->GetHeap();
1771 if (heap->InNewSpace(value)) {
1772 heap->RecordWrite(array->address(), offset);
1773 }
1774}
1775
1776
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001777void FixedArray::NoWriteBarrierSet(FixedArray* array,
1778 int index,
1779 Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001780 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001781 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001782 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001783 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1784}
1785
1786
1787void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001788 ASSERT(map() != HEAP->fixed_cow_array_map());
1789 set_undefined(GetHeap(), index);
1790}
1791
1792
1793void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001794 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001795 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001796 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001797 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001798}
1799
1800
ager@chromium.org236ad962008-09-25 09:45:57 +00001801void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001802 set_null(GetHeap(), index);
1803}
1804
1805
1806void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001807 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001808 ASSERT(!heap->InNewSpace(heap->null_value()));
1809 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001810}
1811
1812
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001813void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001814 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001815 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001816 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1817 WRITE_FIELD(this,
1818 kHeaderSize + index * kPointerSize,
1819 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001820}
1821
1822
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001823void FixedArray::set_unchecked(int index, Smi* value) {
1824 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1825 int offset = kHeaderSize + index * kPointerSize;
1826 WRITE_FIELD(this, offset, value);
1827}
1828
1829
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001830void FixedArray::set_unchecked(Heap* heap,
1831 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001832 Object* value,
1833 WriteBarrierMode mode) {
1834 int offset = kHeaderSize + index * kPointerSize;
1835 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001836 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001837}
1838
1839
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001840void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001841 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001842 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1843 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001844}
1845
1846
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001847Object** FixedArray::data_start() {
1848 return HeapObject::RawField(this, kHeaderSize);
1849}
1850
1851
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001852bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001853 ASSERT(this->IsSmi() ||
1854 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001855 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001856 return this->IsSmi() || length() <= kFirstIndex;
1857}
1858
1859
1860int DescriptorArray::bit_field3_storage() {
1861 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1862 return Smi::cast(storage)->value();
1863}
1864
1865void DescriptorArray::set_bit_field3_storage(int value) {
1866 ASSERT(!IsEmpty());
1867 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001868}
1869
1870
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001871void DescriptorArray::NoIncrementalWriteBarrierSwap(FixedArray* array,
1872 int first,
1873 int second) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001874 Object* tmp = array->get(first);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001875 NoIncrementalWriteBarrierSet(array, first, array->get(second));
1876 NoIncrementalWriteBarrierSet(array, second, tmp);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001877}
1878
1879
1880int DescriptorArray::Search(String* name) {
1881 SLOW_ASSERT(IsSortedNoDuplicates());
1882
1883 // Check for empty descriptor array.
1884 int nof = number_of_descriptors();
1885 if (nof == 0) return kNotFound;
1886
1887 // Fast case: do linear search for small arrays.
1888 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001889 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001890 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001891 }
1892
1893 // Slow case: perform binary search.
1894 return BinarySearch(name, 0, nof - 1);
1895}
1896
1897
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001898int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001899 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001900 if (number == DescriptorLookupCache::kAbsent) {
1901 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001902 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001903 }
1904 return number;
1905}
1906
1907
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001908String* DescriptorArray::GetKey(int descriptor_number) {
1909 ASSERT(descriptor_number < number_of_descriptors());
1910 return String::cast(get(ToKeyIndex(descriptor_number)));
1911}
1912
1913
1914Object* DescriptorArray::GetValue(int descriptor_number) {
1915 ASSERT(descriptor_number < number_of_descriptors());
1916 return GetContentArray()->get(ToValueIndex(descriptor_number));
1917}
1918
1919
1920Smi* DescriptorArray::GetDetails(int descriptor_number) {
1921 ASSERT(descriptor_number < number_of_descriptors());
1922 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1923}
1924
1925
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001926PropertyType DescriptorArray::GetType(int descriptor_number) {
1927 ASSERT(descriptor_number < number_of_descriptors());
1928 return PropertyDetails(GetDetails(descriptor_number)).type();
1929}
1930
1931
1932int DescriptorArray::GetFieldIndex(int descriptor_number) {
1933 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1934}
1935
1936
1937JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1938 return JSFunction::cast(GetValue(descriptor_number));
1939}
1940
1941
1942Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1943 ASSERT(GetType(descriptor_number) == CALLBACKS);
1944 return GetValue(descriptor_number);
1945}
1946
1947
1948AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1949 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001950 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00001951 return reinterpret_cast<AccessorDescriptor*>(p->foreign_address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001952}
1953
1954
1955bool DescriptorArray::IsProperty(int descriptor_number) {
danno@chromium.orgc612e022011-11-10 11:38:15 +00001956 return IsRealProperty(GetType(descriptor_number));
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001957}
1958
1959
1960bool DescriptorArray::IsTransition(int descriptor_number) {
danno@chromium.orgc612e022011-11-10 11:38:15 +00001961 return IsTransitionType(GetType(descriptor_number));
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001962}
1963
1964
1965bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1966 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1967}
1968
1969
1970bool DescriptorArray::IsDontEnum(int descriptor_number) {
1971 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1972}
1973
1974
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001975void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1976 desc->Init(GetKey(descriptor_number),
1977 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001978 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001979}
1980
1981
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00001982void DescriptorArray::Set(int descriptor_number,
1983 Descriptor* desc,
1984 const WhitenessWitness&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001985 // Range check.
1986 ASSERT(descriptor_number < number_of_descriptors());
1987
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001988 NoIncrementalWriteBarrierSet(this,
1989 ToKeyIndex(descriptor_number),
1990 desc->GetKey());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001991 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00001992 NoIncrementalWriteBarrierSet(content_array,
1993 ToValueIndex(descriptor_number),
1994 desc->GetValue());
1995 NoIncrementalWriteBarrierSet(content_array,
1996 ToDetailsIndex(descriptor_number),
1997 desc->GetDetails().AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001998}
1999
2000
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002001void DescriptorArray::CopyFrom(int index,
2002 DescriptorArray* src,
2003 int src_index,
2004 const WhitenessWitness& witness) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002005 Descriptor desc;
2006 src->Get(src_index, &desc);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002007 Set(index, &desc, witness);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002008}
2009
2010
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002011void DescriptorArray::NoIncrementalWriteBarrierSwapDescriptors(
2012 int first, int second) {
2013 NoIncrementalWriteBarrierSwap(this, ToKeyIndex(first), ToKeyIndex(second));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002014 FixedArray* content_array = GetContentArray();
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00002015 NoIncrementalWriteBarrierSwap(content_array,
2016 ToValueIndex(first),
2017 ToValueIndex(second));
2018 NoIncrementalWriteBarrierSwap(content_array,
2019 ToDetailsIndex(first),
2020 ToDetailsIndex(second));
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002021}
2022
2023
2024DescriptorArray::WhitenessWitness::WhitenessWitness(DescriptorArray* array)
2025 : marking_(array->GetHeap()->incremental_marking()) {
2026 marking_->EnterNoMarkingScope();
2027 if (array->number_of_descriptors() > 0) {
2028 ASSERT(Marking::Color(array) == Marking::WHITE_OBJECT);
2029 ASSERT(Marking::Color(array->GetContentArray()) == Marking::WHITE_OBJECT);
2030 }
2031}
2032
2033
2034DescriptorArray::WhitenessWitness::~WhitenessWitness() {
2035 marking_->LeaveNoMarkingScope();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002036}
2037
2038
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002039template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002040int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2041 const int kMinCapacity = 32;
2042 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2043 if (capacity < kMinCapacity) {
2044 capacity = kMinCapacity; // Guarantee min capacity.
2045 }
2046 return capacity;
2047}
2048
2049
2050template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002051int HashTable<Shape, Key>::FindEntry(Key key) {
2052 return FindEntry(GetIsolate(), key);
2053}
2054
2055
2056// Find entry for key otherwise return kNotFound.
2057template<typename Shape, typename Key>
2058int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2059 uint32_t capacity = Capacity();
2060 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
2061 uint32_t count = 1;
2062 // EnsureCapacity will guarantee the hash table is never full.
2063 while (true) {
2064 Object* element = KeyAt(entry);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00002065 // Empty entry.
2066 if (element == isolate->heap()->raw_unchecked_undefined_value()) break;
2067 if (element != isolate->heap()->raw_unchecked_the_hole_value() &&
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002068 Shape::IsMatch(key, element)) return entry;
2069 entry = NextProbe(entry, count++, capacity);
2070 }
2071 return kNotFound;
2072}
2073
2074
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002075bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002076 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002077 if (!max_index_object->IsSmi()) return false;
2078 return 0 !=
2079 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2080}
2081
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002082uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002083 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002084 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002085 if (!max_index_object->IsSmi()) return 0;
2086 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2087 return value >> kRequiresSlowElementsTagSize;
2088}
2089
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002090void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002091 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002092}
2093
2094
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002095// ------------------------------------
2096// Cast operations
2097
2098
2099CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002100CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002101CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002102CAST_ACCESSOR(DeoptimizationInputData)
2103CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002104CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002105CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002106CAST_ACCESSOR(NormalizedMapCache)
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00002107CAST_ACCESSOR(ScopeInfo)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002108CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002109CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002110CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002111CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002112CAST_ACCESSOR(String)
2113CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002114CAST_ACCESSOR(SeqAsciiString)
2115CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002116CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002117CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002118CAST_ACCESSOR(ExternalString)
2119CAST_ACCESSOR(ExternalAsciiString)
2120CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002121CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002122CAST_ACCESSOR(JSObject)
2123CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002124CAST_ACCESSOR(HeapObject)
2125CAST_ACCESSOR(HeapNumber)
2126CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002127CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002128CAST_ACCESSOR(SharedFunctionInfo)
2129CAST_ACCESSOR(Map)
2130CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002131CAST_ACCESSOR(GlobalObject)
2132CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002133CAST_ACCESSOR(JSGlobalObject)
2134CAST_ACCESSOR(JSBuiltinsObject)
2135CAST_ACCESSOR(Code)
2136CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002137CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002138CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002139CAST_ACCESSOR(JSFunctionProxy)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00002140CAST_ACCESSOR(JSSet)
2141CAST_ACCESSOR(JSMap)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002142CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002143CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002144CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002145CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002146CAST_ACCESSOR(ExternalArray)
2147CAST_ACCESSOR(ExternalByteArray)
2148CAST_ACCESSOR(ExternalUnsignedByteArray)
2149CAST_ACCESSOR(ExternalShortArray)
2150CAST_ACCESSOR(ExternalUnsignedShortArray)
2151CAST_ACCESSOR(ExternalIntArray)
2152CAST_ACCESSOR(ExternalUnsignedIntArray)
2153CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002154CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002155CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002156CAST_ACCESSOR(Struct)
2157
2158
2159#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2160 STRUCT_LIST(MAKE_STRUCT_CAST)
2161#undef MAKE_STRUCT_CAST
2162
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002163
2164template <typename Shape, typename Key>
2165HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002166 ASSERT(obj->IsHashTable());
2167 return reinterpret_cast<HashTable*>(obj);
2168}
2169
2170
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002171SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002172SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002173
ager@chromium.orgac091b72010-05-05 07:34:42 +00002174SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002175
2176
2177uint32_t String::hash_field() {
2178 return READ_UINT32_FIELD(this, kHashFieldOffset);
2179}
2180
2181
2182void String::set_hash_field(uint32_t value) {
2183 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002184#if V8_HOST_ARCH_64_BIT
2185 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2186#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002187}
2188
2189
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002190bool String::Equals(String* other) {
2191 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002192 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2193 return false;
2194 }
2195 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002196}
2197
2198
lrn@chromium.org303ada72010-10-27 09:33:13 +00002199MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002200 if (!StringShape(this).IsCons()) return this;
2201 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002202 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002203 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002204}
2205
2206
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002207String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002208 MaybeObject* flat = TryFlatten(pretenure);
2209 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002210 if (!flat->ToObject(&successfully_flattened)) return this;
2211 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002212}
2213
2214
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002215uint16_t String::Get(int index) {
2216 ASSERT(index >= 0 && index < length());
2217 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002218 case kSeqStringTag | kAsciiStringTag:
2219 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2220 case kSeqStringTag | kTwoByteStringTag:
2221 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2222 case kConsStringTag | kAsciiStringTag:
2223 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002224 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002225 case kExternalStringTag | kAsciiStringTag:
2226 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2227 case kExternalStringTag | kTwoByteStringTag:
2228 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002229 case kSlicedStringTag | kAsciiStringTag:
2230 case kSlicedStringTag | kTwoByteStringTag:
2231 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002232 default:
2233 break;
2234 }
2235
2236 UNREACHABLE();
2237 return 0;
2238}
2239
2240
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002241void String::Set(int index, uint16_t value) {
2242 ASSERT(index >= 0 && index < length());
2243 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002244
ager@chromium.org5ec48922009-05-05 07:25:34 +00002245 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002246 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2247 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002248}
2249
2250
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002251bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002252 if (!StringShape(this).IsCons()) return true;
2253 return ConsString::cast(this)->second()->length() == 0;
2254}
2255
2256
2257String* String::GetUnderlying() {
2258 // Giving direct access to underlying string only makes sense if the
2259 // wrapping string is already flattened.
2260 ASSERT(this->IsFlat());
2261 ASSERT(StringShape(this).IsIndirect());
2262 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2263 const int kUnderlyingOffset = SlicedString::kParentOffset;
2264 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002265}
2266
2267
ager@chromium.org7c537e22008-10-16 08:43:32 +00002268uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002269 ASSERT(index >= 0 && index < length());
2270 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2271}
2272
2273
ager@chromium.org7c537e22008-10-16 08:43:32 +00002274void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002275 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2276 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2277 static_cast<byte>(value));
2278}
2279
2280
ager@chromium.org7c537e22008-10-16 08:43:32 +00002281Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002282 return FIELD_ADDR(this, kHeaderSize);
2283}
2284
2285
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002286char* SeqAsciiString::GetChars() {
2287 return reinterpret_cast<char*>(GetCharsAddress());
2288}
2289
2290
ager@chromium.org7c537e22008-10-16 08:43:32 +00002291Address SeqTwoByteString::GetCharsAddress() {
2292 return FIELD_ADDR(this, kHeaderSize);
2293}
2294
2295
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002296uc16* SeqTwoByteString::GetChars() {
2297 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2298}
2299
2300
ager@chromium.org7c537e22008-10-16 08:43:32 +00002301uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002302 ASSERT(index >= 0 && index < length());
2303 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2304}
2305
2306
ager@chromium.org7c537e22008-10-16 08:43:32 +00002307void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002308 ASSERT(index >= 0 && index < length());
2309 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2310}
2311
2312
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002313int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002314 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002315}
2316
2317
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002318int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002319 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002320}
2321
2322
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002323String* SlicedString::parent() {
2324 return String::cast(READ_FIELD(this, kParentOffset));
2325}
2326
2327
2328void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002329 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002330 WRITE_FIELD(this, kParentOffset, parent);
2331}
2332
2333
2334SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2335
2336
ager@chromium.org870a0b62008-11-04 11:43:05 +00002337String* ConsString::first() {
2338 return String::cast(READ_FIELD(this, kFirstOffset));
2339}
2340
2341
2342Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002343 return READ_FIELD(this, kFirstOffset);
2344}
2345
2346
ager@chromium.org870a0b62008-11-04 11:43:05 +00002347void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002348 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002349 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002350}
2351
2352
ager@chromium.org870a0b62008-11-04 11:43:05 +00002353String* ConsString::second() {
2354 return String::cast(READ_FIELD(this, kSecondOffset));
2355}
2356
2357
2358Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002359 return READ_FIELD(this, kSecondOffset);
2360}
2361
2362
ager@chromium.org870a0b62008-11-04 11:43:05 +00002363void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002364 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002365 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002366}
2367
2368
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002369bool ExternalString::is_short() {
2370 InstanceType type = map()->instance_type();
2371 return (type & kShortExternalStringMask) == kShortExternalStringTag;
erikcorry0ad885c2011-11-21 13:51:57 +00002372}
2373
2374
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002375const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002376 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2377}
2378
2379
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002380void ExternalAsciiString::update_data_cache() {
2381 if (is_short()) return;
2382 const char** data_field =
2383 reinterpret_cast<const char**>(FIELD_ADDR(this, kResourceDataOffset));
2384 *data_field = resource()->data();
2385}
2386
2387
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002388void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002389 const ExternalAsciiString::Resource* resource) {
2390 *reinterpret_cast<const Resource**>(
2391 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002392 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002393}
2394
2395
2396const char* ExternalAsciiString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002397 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002398}
2399
2400
2401uint16_t ExternalAsciiString::ExternalAsciiStringGet(int index) {
2402 ASSERT(index >= 0 && index < length());
2403 return GetChars()[index];
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002404}
2405
2406
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002407const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002408 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2409}
2410
2411
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002412void ExternalTwoByteString::update_data_cache() {
2413 if (is_short()) return;
2414 const uint16_t** data_field =
2415 reinterpret_cast<const uint16_t**>(FIELD_ADDR(this, kResourceDataOffset));
2416 *data_field = resource()->data();
2417}
2418
2419
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002420void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002421 const ExternalTwoByteString::Resource* resource) {
2422 *reinterpret_cast<const Resource**>(
2423 FIELD_ADDR(this, kResourceOffset)) = resource;
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002424 if (resource != NULL) update_data_cache();
erikcorry0ad885c2011-11-21 13:51:57 +00002425}
2426
2427
2428const uint16_t* ExternalTwoByteString::GetChars() {
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00002429 return resource()->data();
erikcorry0ad885c2011-11-21 13:51:57 +00002430}
2431
2432
2433uint16_t ExternalTwoByteString::ExternalTwoByteStringGet(int index) {
2434 ASSERT(index >= 0 && index < length());
2435 return GetChars()[index];
2436}
2437
2438
2439const uint16_t* ExternalTwoByteString::ExternalTwoByteStringGetData(
2440 unsigned start) {
2441 return GetChars() + start;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002442}
2443
2444
ager@chromium.orgac091b72010-05-05 07:34:42 +00002445void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002446 set_finger_index(kEntriesIndex);
2447 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002448}
2449
2450
2451void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002452 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002453 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002454 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002455 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002456 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002457 MakeZeroSize();
2458}
2459
2460
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002461int JSFunctionResultCache::size() {
2462 return Smi::cast(get(kCacheSizeIndex))->value();
2463}
2464
2465
2466void JSFunctionResultCache::set_size(int size) {
2467 set(kCacheSizeIndex, Smi::FromInt(size));
2468}
2469
2470
2471int JSFunctionResultCache::finger_index() {
2472 return Smi::cast(get(kFingerIndex))->value();
2473}
2474
2475
2476void JSFunctionResultCache::set_finger_index(int finger_index) {
2477 set(kFingerIndex, Smi::FromInt(finger_index));
2478}
2479
2480
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002481byte ByteArray::get(int index) {
2482 ASSERT(index >= 0 && index < this->length());
2483 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2484}
2485
2486
2487void ByteArray::set(int index, byte value) {
2488 ASSERT(index >= 0 && index < this->length());
2489 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2490}
2491
2492
2493int ByteArray::get_int(int index) {
2494 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2495 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2496}
2497
2498
2499ByteArray* ByteArray::FromDataStartAddress(Address address) {
2500 ASSERT_TAG_ALIGNED(address);
2501 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2502}
2503
2504
2505Address ByteArray::GetDataStartAddress() {
2506 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2507}
2508
2509
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002510uint8_t* ExternalPixelArray::external_pixel_pointer() {
2511 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002512}
2513
2514
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002515uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002516 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002517 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002518 return ptr[index];
2519}
2520
2521
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002522MaybeObject* ExternalPixelArray::get(int index) {
2523 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2524}
2525
2526
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002527void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002528 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002529 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002530 ptr[index] = value;
2531}
2532
2533
ager@chromium.org3811b432009-10-28 14:53:37 +00002534void* ExternalArray::external_pointer() {
2535 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2536 return reinterpret_cast<void*>(ptr);
2537}
2538
2539
2540void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2541 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2542 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2543}
2544
2545
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002546int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002547 ASSERT((index >= 0) && (index < this->length()));
2548 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2549 return ptr[index];
2550}
2551
2552
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002553MaybeObject* ExternalByteArray::get(int index) {
2554 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2555}
2556
2557
ager@chromium.org3811b432009-10-28 14:53:37 +00002558void ExternalByteArray::set(int index, int8_t value) {
2559 ASSERT((index >= 0) && (index < this->length()));
2560 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2561 ptr[index] = value;
2562}
2563
2564
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002565uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002566 ASSERT((index >= 0) && (index < this->length()));
2567 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2568 return ptr[index];
2569}
2570
2571
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002572MaybeObject* ExternalUnsignedByteArray::get(int index) {
2573 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2574}
2575
2576
ager@chromium.org3811b432009-10-28 14:53:37 +00002577void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2578 ASSERT((index >= 0) && (index < this->length()));
2579 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2580 ptr[index] = value;
2581}
2582
2583
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002584int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002585 ASSERT((index >= 0) && (index < this->length()));
2586 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2587 return ptr[index];
2588}
2589
2590
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002591MaybeObject* ExternalShortArray::get(int index) {
2592 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2593}
2594
2595
ager@chromium.org3811b432009-10-28 14:53:37 +00002596void ExternalShortArray::set(int index, int16_t value) {
2597 ASSERT((index >= 0) && (index < this->length()));
2598 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2599 ptr[index] = value;
2600}
2601
2602
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002603uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002604 ASSERT((index >= 0) && (index < this->length()));
2605 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2606 return ptr[index];
2607}
2608
2609
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002610MaybeObject* ExternalUnsignedShortArray::get(int index) {
2611 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2612}
2613
2614
ager@chromium.org3811b432009-10-28 14:53:37 +00002615void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2616 ASSERT((index >= 0) && (index < this->length()));
2617 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2618 ptr[index] = value;
2619}
2620
2621
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002622int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002623 ASSERT((index >= 0) && (index < this->length()));
2624 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2625 return ptr[index];
2626}
2627
2628
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002629MaybeObject* ExternalIntArray::get(int index) {
2630 return GetHeap()->NumberFromInt32(get_scalar(index));
2631}
2632
2633
ager@chromium.org3811b432009-10-28 14:53:37 +00002634void ExternalIntArray::set(int index, int32_t value) {
2635 ASSERT((index >= 0) && (index < this->length()));
2636 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2637 ptr[index] = value;
2638}
2639
2640
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002641uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002642 ASSERT((index >= 0) && (index < this->length()));
2643 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2644 return ptr[index];
2645}
2646
2647
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002648MaybeObject* ExternalUnsignedIntArray::get(int index) {
2649 return GetHeap()->NumberFromUint32(get_scalar(index));
2650}
2651
2652
ager@chromium.org3811b432009-10-28 14:53:37 +00002653void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2654 ASSERT((index >= 0) && (index < this->length()));
2655 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2656 ptr[index] = value;
2657}
2658
2659
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002660float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002661 ASSERT((index >= 0) && (index < this->length()));
2662 float* ptr = static_cast<float*>(external_pointer());
2663 return ptr[index];
2664}
2665
2666
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002667MaybeObject* ExternalFloatArray::get(int index) {
2668 return GetHeap()->NumberFromDouble(get_scalar(index));
2669}
2670
2671
ager@chromium.org3811b432009-10-28 14:53:37 +00002672void ExternalFloatArray::set(int index, float value) {
2673 ASSERT((index >= 0) && (index < this->length()));
2674 float* ptr = static_cast<float*>(external_pointer());
2675 ptr[index] = value;
2676}
2677
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002678
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002679double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002680 ASSERT((index >= 0) && (index < this->length()));
2681 double* ptr = static_cast<double*>(external_pointer());
2682 return ptr[index];
2683}
2684
2685
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002686MaybeObject* ExternalDoubleArray::get(int index) {
2687 return GetHeap()->NumberFromDouble(get_scalar(index));
2688}
2689
2690
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002691void ExternalDoubleArray::set(int index, double value) {
2692 ASSERT((index >= 0) && (index < this->length()));
2693 double* ptr = static_cast<double*>(external_pointer());
2694 ptr[index] = value;
2695}
2696
2697
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002698int Map::visitor_id() {
2699 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2700}
2701
2702
2703void Map::set_visitor_id(int id) {
2704 ASSERT(0 <= id && id < 256);
2705 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2706}
2707
ager@chromium.org3811b432009-10-28 14:53:37 +00002708
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002709int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002710 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2711}
2712
2713
2714int Map::inobject_properties() {
2715 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002716}
2717
2718
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002719int Map::pre_allocated_property_fields() {
2720 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2721}
2722
2723
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002724int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002725 int instance_size = map->instance_size();
2726 if (instance_size != kVariableSizeSentinel) return instance_size;
2727 // We can ignore the "symbol" bit becase it is only set for symbols
2728 // and implies a string type.
2729 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002730 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002731 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002732 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002733 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002734 if (instance_type == ASCII_STRING_TYPE) {
2735 return SeqAsciiString::SizeFor(
2736 reinterpret_cast<SeqAsciiString*>(this)->length());
2737 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002738 if (instance_type == BYTE_ARRAY_TYPE) {
2739 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2740 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002741 if (instance_type == FREE_SPACE_TYPE) {
2742 return reinterpret_cast<FreeSpace*>(this)->size();
2743 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002744 if (instance_type == STRING_TYPE) {
2745 return SeqTwoByteString::SizeFor(
2746 reinterpret_cast<SeqTwoByteString*>(this)->length());
2747 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002748 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2749 return FixedDoubleArray::SizeFor(
2750 reinterpret_cast<FixedDoubleArray*>(this)->length());
2751 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002752 ASSERT(instance_type == CODE_TYPE);
2753 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002754}
2755
2756
2757void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002758 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002759 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002760 ASSERT(0 <= value && value < 256);
2761 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2762}
2763
2764
ager@chromium.org7c537e22008-10-16 08:43:32 +00002765void Map::set_inobject_properties(int value) {
2766 ASSERT(0 <= value && value < 256);
2767 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2768}
2769
2770
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002771void Map::set_pre_allocated_property_fields(int value) {
2772 ASSERT(0 <= value && value < 256);
2773 WRITE_BYTE_FIELD(this,
2774 kPreAllocatedPropertyFieldsOffset,
2775 static_cast<byte>(value));
2776}
2777
2778
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002779InstanceType Map::instance_type() {
2780 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2781}
2782
2783
2784void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002785 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2786}
2787
2788
2789int Map::unused_property_fields() {
2790 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2791}
2792
2793
2794void Map::set_unused_property_fields(int value) {
2795 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2796}
2797
2798
2799byte Map::bit_field() {
2800 return READ_BYTE_FIELD(this, kBitFieldOffset);
2801}
2802
2803
2804void Map::set_bit_field(byte value) {
2805 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2806}
2807
2808
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002809byte Map::bit_field2() {
2810 return READ_BYTE_FIELD(this, kBitField2Offset);
2811}
2812
2813
2814void Map::set_bit_field2(byte value) {
2815 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2816}
2817
2818
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002819void Map::set_non_instance_prototype(bool value) {
2820 if (value) {
2821 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2822 } else {
2823 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2824 }
2825}
2826
2827
2828bool Map::has_non_instance_prototype() {
2829 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2830}
2831
2832
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002833void Map::set_function_with_prototype(bool value) {
2834 if (value) {
2835 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2836 } else {
2837 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2838 }
2839}
2840
2841
2842bool Map::function_with_prototype() {
2843 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2844}
2845
2846
ager@chromium.org870a0b62008-11-04 11:43:05 +00002847void Map::set_is_access_check_needed(bool access_check_needed) {
2848 if (access_check_needed) {
2849 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2850 } else {
2851 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2852 }
2853}
2854
2855
2856bool Map::is_access_check_needed() {
2857 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2858}
2859
2860
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002861void Map::set_is_extensible(bool value) {
2862 if (value) {
2863 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2864 } else {
2865 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2866 }
2867}
2868
2869bool Map::is_extensible() {
2870 return ((1 << kIsExtensible) & bit_field2()) != 0;
2871}
2872
2873
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002874void Map::set_attached_to_shared_function_info(bool value) {
2875 if (value) {
2876 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2877 } else {
2878 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2879 }
2880}
2881
2882bool Map::attached_to_shared_function_info() {
2883 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2884}
2885
2886
2887void Map::set_is_shared(bool value) {
2888 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002889 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002890 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002891 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002892 }
2893}
2894
2895bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002896 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002897}
2898
2899
2900JSFunction* Map::unchecked_constructor() {
2901 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2902}
2903
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002904
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002905Code::Flags Code::flags() {
2906 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2907}
2908
2909
2910void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002911 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002912 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002913 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2914 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002915 ExtractArgumentsCountFromFlags(flags) >= 0);
2916 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2917}
2918
2919
2920Code::Kind Code::kind() {
2921 return ExtractKindFromFlags(flags());
2922}
2923
2924
kasper.lund7276f142008-07-30 08:49:36 +00002925InlineCacheState Code::ic_state() {
2926 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002927 // Only allow uninitialized or debugger states for non-IC code
2928 // objects. This is used in the debugger to determine whether or not
2929 // a call to code object has been replaced with a debug break call.
2930 ASSERT(is_inline_cache_stub() ||
2931 result == UNINITIALIZED ||
2932 result == DEBUG_BREAK ||
2933 result == DEBUG_PREPARE_STEP_IN);
2934 return result;
2935}
2936
2937
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002938Code::ExtraICState Code::extra_ic_state() {
2939 ASSERT(is_inline_cache_stub());
2940 return ExtractExtraICStateFromFlags(flags());
2941}
2942
2943
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002944PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002945 return ExtractTypeFromFlags(flags());
2946}
2947
2948
2949int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002950 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002951 return ExtractArgumentsCountFromFlags(flags());
2952}
2953
2954
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002955int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002956 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002957 kind() == UNARY_OP_IC ||
2958 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002959 kind() == COMPARE_IC ||
2960 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002961 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002962}
2963
2964
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002965void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002966 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002967 kind() == UNARY_OP_IC ||
2968 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002969 kind() == COMPARE_IC ||
2970 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002971 ASSERT(0 <= major && major < 256);
2972 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002973}
2974
2975
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002976bool Code::is_pregenerated() {
2977 return kind() == STUB && IsPregeneratedField::decode(flags());
2978}
2979
2980
2981void Code::set_is_pregenerated(bool value) {
2982 ASSERT(kind() == STUB);
2983 Flags f = flags();
2984 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
2985 set_flags(f);
2986}
2987
2988
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002989bool Code::optimizable() {
2990 ASSERT(kind() == FUNCTION);
2991 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2992}
2993
2994
2995void Code::set_optimizable(bool value) {
2996 ASSERT(kind() == FUNCTION);
2997 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2998}
2999
3000
3001bool Code::has_deoptimization_support() {
3002 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00003003 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3004 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003005}
3006
3007
3008void Code::set_has_deoptimization_support(bool value) {
3009 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00003010 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3011 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
3012 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3013}
3014
3015
3016bool Code::has_debug_break_slots() {
3017 ASSERT(kind() == FUNCTION);
3018 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3019 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
3020}
3021
3022
3023void Code::set_has_debug_break_slots(bool value) {
3024 ASSERT(kind() == FUNCTION);
3025 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3026 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
3027 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003028}
3029
3030
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003031bool Code::is_compiled_optimizable() {
3032 ASSERT(kind() == FUNCTION);
3033 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3034 return FullCodeFlagsIsCompiledOptimizable::decode(flags);
3035}
3036
3037
3038void Code::set_compiled_optimizable(bool value) {
3039 ASSERT(kind() == FUNCTION);
3040 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
3041 flags = FullCodeFlagsIsCompiledOptimizable::update(flags, value);
3042 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
3043}
3044
3045
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003046int Code::allow_osr_at_loop_nesting_level() {
3047 ASSERT(kind() == FUNCTION);
3048 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
3049}
3050
3051
3052void Code::set_allow_osr_at_loop_nesting_level(int level) {
3053 ASSERT(kind() == FUNCTION);
3054 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
3055 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
3056}
3057
3058
3059unsigned Code::stack_slots() {
3060 ASSERT(kind() == OPTIMIZED_FUNCTION);
3061 return READ_UINT32_FIELD(this, kStackSlotsOffset);
3062}
3063
3064
3065void Code::set_stack_slots(unsigned slots) {
3066 ASSERT(kind() == OPTIMIZED_FUNCTION);
3067 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
3068}
3069
3070
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003071unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003072 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003073 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003074}
3075
3076
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003077void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003078 ASSERT(kind() == OPTIMIZED_FUNCTION);
3079 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003080 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003081}
3082
3083
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003084unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003085 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003086 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003087}
3088
3089
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003090void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003091 ASSERT(kind() == FUNCTION);
3092 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003093 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003094}
3095
3096
3097CheckType Code::check_type() {
3098 ASSERT(is_call_stub() || is_keyed_call_stub());
3099 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3100 return static_cast<CheckType>(type);
3101}
3102
3103
3104void Code::set_check_type(CheckType value) {
3105 ASSERT(is_call_stub() || is_keyed_call_stub());
3106 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3107}
3108
3109
danno@chromium.org40cb8782011-05-25 07:58:50 +00003110byte Code::unary_op_type() {
3111 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003112 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3113}
3114
3115
danno@chromium.org40cb8782011-05-25 07:58:50 +00003116void Code::set_unary_op_type(byte value) {
3117 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003118 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3119}
3120
3121
danno@chromium.org40cb8782011-05-25 07:58:50 +00003122byte Code::binary_op_type() {
3123 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003124 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3125}
3126
3127
danno@chromium.org40cb8782011-05-25 07:58:50 +00003128void Code::set_binary_op_type(byte value) {
3129 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003130 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3131}
3132
3133
danno@chromium.org40cb8782011-05-25 07:58:50 +00003134byte Code::binary_op_result_type() {
3135 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003136 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3137}
3138
3139
danno@chromium.org40cb8782011-05-25 07:58:50 +00003140void Code::set_binary_op_result_type(byte value) {
3141 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003142 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3143}
3144
3145
3146byte Code::compare_state() {
3147 ASSERT(is_compare_ic_stub());
3148 return READ_BYTE_FIELD(this, kCompareStateOffset);
3149}
3150
3151
3152void Code::set_compare_state(byte value) {
3153 ASSERT(is_compare_ic_stub());
3154 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3155}
3156
3157
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003158byte Code::to_boolean_state() {
3159 ASSERT(is_to_boolean_ic_stub());
3160 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3161}
3162
3163
3164void Code::set_to_boolean_state(byte value) {
3165 ASSERT(is_to_boolean_ic_stub());
3166 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3167}
3168
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003169
3170bool Code::has_function_cache() {
3171 ASSERT(kind() == STUB);
3172 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3173}
3174
3175
3176void Code::set_has_function_cache(bool flag) {
3177 ASSERT(kind() == STUB);
3178 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3179}
3180
3181
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003182bool Code::is_inline_cache_stub() {
3183 Kind kind = this->kind();
3184 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3185}
3186
3187
3188Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003189 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003190 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003191 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003192 int argc,
3193 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003194 // Extra IC state is only allowed for call IC stubs or for store IC
3195 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003196 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003197 kind == CALL_IC ||
3198 kind == STORE_IC ||
3199 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003200 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003201 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003202 | ICStateField::encode(ic_state)
3203 | TypeField::encode(type)
3204 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003205 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003206 | CacheHolderField::encode(holder);
3207 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003208}
3209
3210
3211Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3212 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003213 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003214 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003215 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003216 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003217}
3218
3219
3220Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003221 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003222}
3223
3224
kasper.lund7276f142008-07-30 08:49:36 +00003225InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003226 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003227}
3228
3229
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003230Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003231 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003232}
3233
3234
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003235PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003236 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003237}
3238
3239
3240int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003241 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003242}
3243
3244
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003245InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003246 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003247}
3248
3249
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003250Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003251 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003252 return static_cast<Flags>(bits);
3253}
3254
3255
ager@chromium.org8bb60582008-12-11 12:02:20 +00003256Code* Code::GetCodeFromTargetAddress(Address address) {
3257 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3258 // GetCodeFromTargetAddress might be called when marking objects during mark
3259 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3260 // Code::cast. Code::cast does not work when the object's map is
3261 // marked.
3262 Code* result = reinterpret_cast<Code*>(code);
3263 return result;
3264}
3265
3266
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003267Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3268 return HeapObject::
3269 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3270}
3271
3272
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003273Object* Map::prototype() {
3274 return READ_FIELD(this, kPrototypeOffset);
3275}
3276
3277
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003278void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003279 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003280 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003281 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003282}
3283
3284
danno@chromium.org40cb8782011-05-25 07:58:50 +00003285DescriptorArray* Map::instance_descriptors() {
3286 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3287 if (object->IsSmi()) {
3288 return HEAP->empty_descriptor_array();
3289 } else {
3290 return DescriptorArray::cast(object);
3291 }
3292}
3293
3294
3295void Map::init_instance_descriptors() {
3296 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3297}
3298
3299
3300void Map::clear_instance_descriptors() {
3301 Object* object = READ_FIELD(this,
3302 kInstanceDescriptorsOrBitField3Offset);
3303 if (!object->IsSmi()) {
3304 WRITE_FIELD(
3305 this,
3306 kInstanceDescriptorsOrBitField3Offset,
3307 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3308 }
3309}
3310
3311
3312void Map::set_instance_descriptors(DescriptorArray* value,
3313 WriteBarrierMode mode) {
3314 Object* object = READ_FIELD(this,
3315 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003316 Heap* heap = GetHeap();
3317 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003318 clear_instance_descriptors();
3319 return;
3320 } else {
3321 if (object->IsSmi()) {
3322 value->set_bit_field3_storage(Smi::cast(object)->value());
3323 } else {
3324 value->set_bit_field3_storage(
3325 DescriptorArray::cast(object)->bit_field3_storage());
3326 }
3327 }
3328 ASSERT(!is_shared());
3329 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003330 CONDITIONAL_WRITE_BARRIER(
3331 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003332}
3333
3334
3335int Map::bit_field3() {
3336 Object* object = READ_FIELD(this,
3337 kInstanceDescriptorsOrBitField3Offset);
3338 if (object->IsSmi()) {
3339 return Smi::cast(object)->value();
3340 } else {
3341 return DescriptorArray::cast(object)->bit_field3_storage();
3342 }
3343}
3344
3345
3346void Map::set_bit_field3(int value) {
3347 ASSERT(Smi::IsValid(value));
3348 Object* object = READ_FIELD(this,
3349 kInstanceDescriptorsOrBitField3Offset);
3350 if (object->IsSmi()) {
3351 WRITE_FIELD(this,
3352 kInstanceDescriptorsOrBitField3Offset,
3353 Smi::FromInt(value));
3354 } else {
3355 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3356 }
3357}
3358
3359
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003360FixedArray* Map::unchecked_prototype_transitions() {
3361 return reinterpret_cast<FixedArray*>(
3362 READ_FIELD(this, kPrototypeTransitionsOffset));
3363}
3364
3365
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003366ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003367ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003368ACCESSORS(Map, constructor, Object, kConstructorOffset)
3369
3370ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003371ACCESSORS(JSFunction, literals_or_bindings, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003372ACCESSORS(JSFunction,
3373 next_function_link,
3374 Object,
3375 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003376
3377ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3378ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003379ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003380
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003381ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003382
3383ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3384ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3385ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3386ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3387ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3388
3389ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3390ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3391ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3392
3393ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3394ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3395ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3396ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3397ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3398ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3399
3400ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3401ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3402
3403ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3404ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3405
3406ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3407ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003408ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3409 kPropertyAccessorsOffset)
3410ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3411 kPrototypeTemplateOffset)
3412ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3413ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3414 kNamedPropertyHandlerOffset)
3415ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3416 kIndexedPropertyHandlerOffset)
3417ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3418 kInstanceTemplateOffset)
3419ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3420ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003421ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3422 kInstanceCallHandlerOffset)
3423ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3424 kAccessCheckInfoOffset)
3425ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3426
3427ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003428ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3429 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003430
3431ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3432ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3433
3434ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3435
3436ACCESSORS(Script, source, Object, kSourceOffset)
3437ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003438ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003439ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3440ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003441ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003442ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003443ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003444ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003445ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003446ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003447ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003448ACCESSORS(Script, eval_from_instructions_offset, Smi,
3449 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003450
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003451#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003452ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3453ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3454ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3455ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3456
3457ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3458ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3459ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3460ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003461#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003462
3463ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003464ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3465ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003466ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3467 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003468ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003469ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3470ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003471ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003472ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3473 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003474
3475BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3476 kHiddenPrototypeBit)
3477BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3478BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3479 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003480BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3481 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003482BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3483 kIsExpressionBit)
3484BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3485 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003486BOOL_GETTER(SharedFunctionInfo,
3487 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003488 has_only_simple_this_property_assignments,
3489 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003490BOOL_ACCESSORS(SharedFunctionInfo,
3491 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003492 allows_lazy_compilation,
3493 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003494BOOL_ACCESSORS(SharedFunctionInfo,
3495 compiler_hints,
3496 uses_arguments,
3497 kUsesArguments)
3498BOOL_ACCESSORS(SharedFunctionInfo,
3499 compiler_hints,
3500 has_duplicate_parameters,
3501 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003502
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003503
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003504#if V8_HOST_ARCH_32_BIT
3505SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3506SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003507 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003508SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003509 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003510SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3511SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003512 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003513SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3514SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003515 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003516SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003517 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003518SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003519 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003520SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003521#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003522
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003523#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003524 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003525 int holder::name() { \
3526 int value = READ_INT_FIELD(this, offset); \
3527 ASSERT(kHeapObjectTag == 1); \
3528 ASSERT((value & kHeapObjectTag) == 0); \
3529 return value >> 1; \
3530 } \
3531 void holder::set_##name(int value) { \
3532 ASSERT(kHeapObjectTag == 1); \
3533 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3534 (value & 0xC0000000) == 0x000000000); \
3535 WRITE_INT_FIELD(this, \
3536 offset, \
3537 (value << 1) & ~kHeapObjectTag); \
3538 }
3539
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003540#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3541 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003542 INT_ACCESSORS(holder, name, offset)
3543
3544
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003545PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003546PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3547 formal_parameter_count,
3548 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003549
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003550PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3551 expected_nof_properties,
3552 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003553PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3554
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003555PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3556PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3557 start_position_and_type,
3558 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003559
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003560PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3561 function_token_position,
3562 kFunctionTokenPositionOffset)
3563PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3564 compiler_hints,
3565 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003566
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003567PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3568 this_property_assignments_count,
3569 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003570PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003571#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003572
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003573
3574int SharedFunctionInfo::construction_count() {
3575 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3576}
3577
3578
3579void SharedFunctionInfo::set_construction_count(int value) {
3580 ASSERT(0 <= value && value < 256);
3581 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3582}
3583
3584
whesse@chromium.org7b260152011-06-20 15:33:18 +00003585BOOL_ACCESSORS(SharedFunctionInfo,
3586 compiler_hints,
3587 live_objects_may_exist,
3588 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003589
3590
3591bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003592 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003593}
3594
3595
whesse@chromium.org7b260152011-06-20 15:33:18 +00003596BOOL_GETTER(SharedFunctionInfo,
3597 compiler_hints,
3598 optimization_disabled,
3599 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003600
3601
3602void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3603 set_compiler_hints(BooleanBit::set(compiler_hints(),
3604 kOptimizationDisabled,
3605 disable));
3606 // If disabling optimizations we reflect that in the code object so
3607 // it will not be counted as optimizable code.
3608 if ((code()->kind() == Code::FUNCTION) && disable) {
3609 code()->set_optimizable(false);
3610 }
3611}
3612
3613
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003614LanguageMode SharedFunctionInfo::language_mode() {
3615 int hints = compiler_hints();
3616 if (BooleanBit::get(hints, kExtendedModeFunction)) {
3617 ASSERT(BooleanBit::get(hints, kStrictModeFunction));
3618 return EXTENDED_MODE;
3619 }
3620 return BooleanBit::get(hints, kStrictModeFunction)
3621 ? STRICT_MODE : CLASSIC_MODE;
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003622}
3623
3624
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003625void SharedFunctionInfo::set_language_mode(LanguageMode language_mode) {
3626 // We only allow language mode transitions that go set the same language mode
3627 // again or go up in the chain:
3628 // CLASSIC_MODE -> STRICT_MODE -> EXTENDED_MODE.
3629 ASSERT(this->language_mode() == CLASSIC_MODE ||
3630 this->language_mode() == language_mode ||
3631 language_mode == EXTENDED_MODE);
3632 int hints = compiler_hints();
3633 hints = BooleanBit::set(
3634 hints, kStrictModeFunction, language_mode != CLASSIC_MODE);
3635 hints = BooleanBit::set(
3636 hints, kExtendedModeFunction, language_mode == EXTENDED_MODE);
3637 set_compiler_hints(hints);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003638}
3639
3640
mstarzinger@chromium.org1b3afd12011-11-29 14:28:56 +00003641bool SharedFunctionInfo::is_classic_mode() {
3642 return !BooleanBit::get(compiler_hints(), kStrictModeFunction);
3643}
3644
3645BOOL_GETTER(SharedFunctionInfo, compiler_hints, is_extended_mode,
3646 kExtendedModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003647BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3648BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3649 name_should_print_as_anonymous,
3650 kNameShouldPrintAsAnonymous)
3651BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3652BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003653
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003654ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3655ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3656
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003657ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3658
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003659bool Script::HasValidSource() {
3660 Object* src = this->source();
3661 if (!src->IsString()) return true;
3662 String* src_str = String::cast(src);
3663 if (!StringShape(src_str).IsExternal()) return true;
3664 if (src_str->IsAsciiRepresentation()) {
3665 return ExternalAsciiString::cast(src)->resource() != NULL;
3666 } else if (src_str->IsTwoByteRepresentation()) {
3667 return ExternalTwoByteString::cast(src)->resource() != NULL;
3668 }
3669 return true;
3670}
3671
3672
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003673void SharedFunctionInfo::DontAdaptArguments() {
3674 ASSERT(code()->kind() == Code::BUILTIN);
3675 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3676}
3677
3678
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003679int SharedFunctionInfo::start_position() {
3680 return start_position_and_type() >> kStartPositionShift;
3681}
3682
3683
3684void SharedFunctionInfo::set_start_position(int start_position) {
3685 set_start_position_and_type((start_position << kStartPositionShift)
3686 | (start_position_and_type() & ~kStartPositionMask));
3687}
3688
3689
3690Code* SharedFunctionInfo::code() {
3691 return Code::cast(READ_FIELD(this, kCodeOffset));
3692}
3693
3694
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003695Code* SharedFunctionInfo::unchecked_code() {
3696 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3697}
3698
3699
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003700void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003701 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003702 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003703}
3704
3705
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003706ScopeInfo* SharedFunctionInfo::scope_info() {
3707 return reinterpret_cast<ScopeInfo*>(READ_FIELD(this, kScopeInfoOffset));
ager@chromium.orgb5737492010-07-15 09:29:43 +00003708}
3709
3710
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00003711void SharedFunctionInfo::set_scope_info(ScopeInfo* value,
ager@chromium.orgb5737492010-07-15 09:29:43 +00003712 WriteBarrierMode mode) {
3713 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003714 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3715 this,
3716 kScopeInfoOffset,
3717 reinterpret_cast<Object*>(value),
3718 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003719}
3720
3721
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003722Smi* SharedFunctionInfo::deopt_counter() {
3723 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3724}
3725
3726
3727void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3728 WRITE_FIELD(this, kDeoptCounterOffset, value);
3729}
3730
3731
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003732bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003733 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003734 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003735}
3736
3737
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003738bool SharedFunctionInfo::IsApiFunction() {
3739 return function_data()->IsFunctionTemplateInfo();
3740}
3741
3742
3743FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3744 ASSERT(IsApiFunction());
3745 return FunctionTemplateInfo::cast(function_data());
3746}
3747
3748
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003749bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003750 return function_data()->IsSmi();
3751}
3752
3753
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003754BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3755 ASSERT(HasBuiltinFunctionId());
3756 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003757}
3758
3759
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003760int SharedFunctionInfo::code_age() {
3761 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3762}
3763
3764
3765void SharedFunctionInfo::set_code_age(int code_age) {
mstarzinger@chromium.orgf8c6bd52011-11-23 12:13:52 +00003766 int hints = compiler_hints() & ~(kCodeAgeMask << kCodeAgeShift);
3767 set_compiler_hints(hints | ((code_age & kCodeAgeMask) << kCodeAgeShift));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003768}
3769
3770
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003771bool SharedFunctionInfo::has_deoptimization_support() {
3772 Code* code = this->code();
3773 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3774}
3775
3776
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003777bool JSFunction::IsBuiltin() {
3778 return context()->global()->IsJSBuiltinsObject();
3779}
3780
3781
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003782bool JSFunction::NeedsArgumentsAdaption() {
3783 return shared()->formal_parameter_count() !=
3784 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3785}
3786
3787
3788bool JSFunction::IsOptimized() {
3789 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3790}
3791
3792
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003793bool JSFunction::IsOptimizable() {
3794 return code()->kind() == Code::FUNCTION && code()->optimizable();
3795}
3796
3797
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003798bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003799 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003800}
3801
3802
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003803Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003804 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003805}
3806
3807
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003808Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003809 return reinterpret_cast<Code*>(
3810 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003811}
3812
3813
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003814void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003815 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003816 Address entry = value->entry();
3817 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003818 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3819 this,
3820 HeapObject::RawField(this, kCodeEntryOffset),
3821 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003822}
3823
3824
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003825void JSFunction::ReplaceCode(Code* code) {
3826 bool was_optimized = IsOptimized();
3827 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3828
3829 set_code(code);
3830
3831 // Add/remove the function from the list of optimized functions for this
3832 // context based on the state change.
3833 if (!was_optimized && is_optimized) {
3834 context()->global_context()->AddOptimizedFunction(this);
3835 }
3836 if (was_optimized && !is_optimized) {
3837 context()->global_context()->RemoveOptimizedFunction(this);
3838 }
3839}
3840
3841
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003842Context* JSFunction::context() {
3843 return Context::cast(READ_FIELD(this, kContextOffset));
3844}
3845
3846
3847Object* JSFunction::unchecked_context() {
3848 return READ_FIELD(this, kContextOffset);
3849}
3850
3851
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003852SharedFunctionInfo* JSFunction::unchecked_shared() {
3853 return reinterpret_cast<SharedFunctionInfo*>(
3854 READ_FIELD(this, kSharedFunctionInfoOffset));
3855}
3856
3857
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003858void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003859 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003860 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003861 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003862}
3863
3864ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3865 kPrototypeOrInitialMapOffset)
3866
3867
3868Map* JSFunction::initial_map() {
3869 return Map::cast(prototype_or_initial_map());
3870}
3871
3872
3873void JSFunction::set_initial_map(Map* value) {
3874 set_prototype_or_initial_map(value);
3875}
3876
3877
3878bool JSFunction::has_initial_map() {
3879 return prototype_or_initial_map()->IsMap();
3880}
3881
3882
3883bool JSFunction::has_instance_prototype() {
3884 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3885}
3886
3887
3888bool JSFunction::has_prototype() {
3889 return map()->has_non_instance_prototype() || has_instance_prototype();
3890}
3891
3892
3893Object* JSFunction::instance_prototype() {
3894 ASSERT(has_instance_prototype());
3895 if (has_initial_map()) return initial_map()->prototype();
3896 // When there is no initial map and the prototype is a JSObject, the
3897 // initial map field is used for the prototype field.
3898 return prototype_or_initial_map();
3899}
3900
3901
3902Object* JSFunction::prototype() {
3903 ASSERT(has_prototype());
3904 // If the function's prototype property has been set to a non-JSObject
3905 // value, that value is stored in the constructor field of the map.
3906 if (map()->has_non_instance_prototype()) return map()->constructor();
3907 return instance_prototype();
3908}
3909
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003910bool JSFunction::should_have_prototype() {
3911 return map()->function_with_prototype();
3912}
3913
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003914
3915bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003916 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003917}
3918
3919
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003920FixedArray* JSFunction::literals() {
3921 ASSERT(!shared()->bound());
3922 return literals_or_bindings();
3923}
3924
3925
3926void JSFunction::set_literals(FixedArray* literals) {
3927 ASSERT(!shared()->bound());
3928 set_literals_or_bindings(literals);
3929}
3930
3931
3932FixedArray* JSFunction::function_bindings() {
3933 ASSERT(shared()->bound());
3934 return literals_or_bindings();
3935}
3936
3937
3938void JSFunction::set_function_bindings(FixedArray* bindings) {
3939 ASSERT(shared()->bound());
3940 // Bound function literal may be initialized to the empty fixed array
3941 // before the bindings are set.
3942 ASSERT(bindings == GetHeap()->empty_fixed_array() ||
3943 bindings->map() == GetHeap()->fixed_cow_array_map());
3944 set_literals_or_bindings(bindings);
3945}
3946
3947
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003948int JSFunction::NumberOfLiterals() {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003949 ASSERT(!shared()->bound());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003950 return literals()->length();
3951}
3952
3953
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003954Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003955 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003956 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003957}
3958
3959
3960void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3961 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003962 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003963 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003964 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003965}
3966
3967
3968Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003969 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003970 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3971}
3972
3973
3974void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3975 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003976 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003977 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003978 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003979}
3980
3981
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003982ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003983ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003984ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
3985ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
3986
3987
3988void JSProxy::InitializeBody(int object_size, Object* value) {
3989 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
3990 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
3991 WRITE_FIELD(this, offset, value);
3992 }
3993}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003994
3995
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00003996ACCESSORS(JSSet, table, Object, kTableOffset)
3997ACCESSORS(JSMap, table, Object, kTableOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003998ACCESSORS(JSWeakMap, table, Object, kTableOffset)
3999ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004000
4001
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004002Address Foreign::foreign_address() {
4003 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kForeignAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004004}
4005
4006
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004007void Foreign::set_foreign_address(Address value) {
4008 WRITE_INTPTR_FIELD(this, kForeignAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004009}
4010
4011
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004012ACCESSORS(JSValue, value, Object, kValueOffset)
4013
4014
4015JSValue* JSValue::cast(Object* obj) {
4016 ASSERT(obj->IsJSValue());
4017 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
4018 return reinterpret_cast<JSValue*>(obj);
4019}
4020
4021
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00004022ACCESSORS(JSMessageObject, type, String, kTypeOffset)
4023ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
4024ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
4025ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
4026ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
4027SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
4028SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
4029
4030
4031JSMessageObject* JSMessageObject::cast(Object* obj) {
4032 ASSERT(obj->IsJSMessageObject());
4033 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
4034 return reinterpret_cast<JSMessageObject*>(obj);
4035}
4036
4037
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004038INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004039ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
jkummerow@chromium.org04e4f1e2011-11-14 13:36:17 +00004040ACCESSORS(Code, handler_table, FixedArray, kHandlerTableOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004041ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00004042ACCESSORS(Code, next_code_flushing_candidate,
4043 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004044
4045
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004046byte* Code::instruction_start() {
4047 return FIELD_ADDR(this, kHeaderSize);
4048}
4049
4050
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004051byte* Code::instruction_end() {
4052 return instruction_start() + instruction_size();
4053}
4054
4055
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004056int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004057 return RoundUp(instruction_size(), kObjectAlignment);
4058}
4059
4060
kasperl@chromium.orga5551262010-12-07 12:49:48 +00004061FixedArray* Code::unchecked_deoptimization_data() {
4062 return reinterpret_cast<FixedArray*>(
4063 READ_FIELD(this, kDeoptimizationDataOffset));
4064}
4065
4066
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004067ByteArray* Code::unchecked_relocation_info() {
4068 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004069}
4070
4071
4072byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00004073 return unchecked_relocation_info()->GetDataStartAddress();
4074}
4075
4076
4077int Code::relocation_size() {
4078 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004079}
4080
4081
4082byte* Code::entry() {
4083 return instruction_start();
4084}
4085
4086
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004087bool Code::contains(byte* inner_pointer) {
4088 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004089}
4090
4091
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004092ACCESSORS(JSArray, length, Object, kLengthOffset)
4093
4094
ager@chromium.org236ad962008-09-25 09:45:57 +00004095ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00004096
4097
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004098JSRegExp::Type JSRegExp::TypeTag() {
4099 Object* data = this->data();
4100 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
4101 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
4102 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00004103}
4104
4105
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004106JSRegExp::Type JSRegExp::TypeTagUnchecked() {
4107 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
4108 return static_cast<JSRegExp::Type>(smi->value());
4109}
4110
4111
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00004112int JSRegExp::CaptureCount() {
4113 switch (TypeTag()) {
4114 case ATOM:
4115 return 0;
4116 case IRREGEXP:
4117 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4118 default:
4119 UNREACHABLE();
4120 return -1;
4121 }
4122}
4123
4124
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004125JSRegExp::Flags JSRegExp::GetFlags() {
4126 ASSERT(this->data()->IsFixedArray());
4127 Object* data = this->data();
4128 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4129 return Flags(smi->value());
4130}
4131
4132
4133String* JSRegExp::Pattern() {
4134 ASSERT(this->data()->IsFixedArray());
4135 Object* data = this->data();
4136 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4137 return pattern;
4138}
4139
4140
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004141Object* JSRegExp::DataAt(int index) {
4142 ASSERT(TypeTag() != NOT_COMPILED);
4143 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004144}
4145
4146
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004147Object* JSRegExp::DataAtUnchecked(int index) {
4148 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4149 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4150 return READ_FIELD(fa, offset);
4151}
4152
4153
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004154void JSRegExp::SetDataAt(int index, Object* value) {
4155 ASSERT(TypeTag() != NOT_COMPILED);
4156 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4157 FixedArray::cast(data())->set(index, value);
4158}
4159
4160
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004161void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4162 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4163 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4164 if (value->IsSmi()) {
4165 fa->set_unchecked(index, Smi::cast(value));
4166 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004167 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004168 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4169 }
4170}
4171
4172
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004173ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004174 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004175#if DEBUG
4176 FixedArrayBase* fixed_array =
4177 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4178 Map* map = fixed_array->map();
4179 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004180 (map == GetHeap()->fixed_array_map() ||
4181 map == GetHeap()->fixed_cow_array_map())) ||
4182 (kind == FAST_DOUBLE_ELEMENTS &&
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004183 (fixed_array->IsFixedDoubleArray() ||
4184 fixed_array == GetHeap()->empty_fixed_array())) ||
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004185 (kind == DICTIONARY_ELEMENTS &&
4186 fixed_array->IsFixedArray() &&
4187 fixed_array->IsDictionary()) ||
4188 (kind > DICTIONARY_ELEMENTS));
4189 ASSERT((kind != NON_STRICT_ARGUMENTS_ELEMENTS) ||
4190 (elements()->IsFixedArray() && elements()->length() >= 2));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004191#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004192 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004193}
4194
4195
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004196ElementsAccessor* JSObject::GetElementsAccessor() {
4197 return ElementsAccessor::ForKind(GetElementsKind());
4198}
4199
4200
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004201bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004202 return GetElementsKind() == FAST_ELEMENTS;
4203}
4204
4205
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004206bool JSObject::HasFastSmiOnlyElements() {
4207 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4208}
4209
4210
4211bool JSObject::HasFastTypeElements() {
4212 ElementsKind elements_kind = GetElementsKind();
4213 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4214 elements_kind == FAST_ELEMENTS;
4215}
4216
4217
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004218bool JSObject::HasFastDoubleElements() {
4219 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4220}
4221
4222
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004223bool JSObject::HasDictionaryElements() {
4224 return GetElementsKind() == DICTIONARY_ELEMENTS;
4225}
4226
4227
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004228bool JSObject::HasNonStrictArgumentsElements() {
4229 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4230}
4231
4232
ager@chromium.org3811b432009-10-28 14:53:37 +00004233bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004234 HeapObject* array = elements();
4235 ASSERT(array != NULL);
4236 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004237}
4238
4239
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004240#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4241bool JSObject::HasExternal##name##Elements() { \
4242 HeapObject* array = elements(); \
4243 ASSERT(array != NULL); \
4244 if (!array->IsHeapObject()) \
4245 return false; \
4246 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004247}
4248
4249
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004250EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4251EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4252EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4253EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4254 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4255EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4256EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4257 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4258EXTERNAL_ELEMENTS_CHECK(Float,
4259 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004260EXTERNAL_ELEMENTS_CHECK(Double,
4261 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004262EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004263
4264
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004265bool JSObject::HasNamedInterceptor() {
4266 return map()->has_named_interceptor();
4267}
4268
4269
4270bool JSObject::HasIndexedInterceptor() {
4271 return map()->has_indexed_interceptor();
4272}
4273
4274
lrn@chromium.org303ada72010-10-27 09:33:13 +00004275MaybeObject* JSObject::EnsureWritableFastElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004276 ASSERT(HasFastTypeElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004277 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004278 Isolate* isolate = GetIsolate();
4279 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004280 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004281 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4282 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004283 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4284 return maybe_writable_elems;
4285 }
4286 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004287 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004288 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004289 return writable_elems;
4290}
4291
4292
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004293StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004294 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004295 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004296}
4297
4298
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004299NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004300 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004301 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004302}
4303
4304
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004305bool String::IsHashFieldComputed(uint32_t field) {
4306 return (field & kHashNotComputedMask) == 0;
4307}
4308
4309
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004310bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004311 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004312}
4313
4314
4315uint32_t String::Hash() {
4316 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004317 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004318 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004319 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004320 return ComputeAndSetHash();
4321}
4322
4323
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004324StringHasher::StringHasher(int length, uint32_t seed)
ager@chromium.org7c537e22008-10-16 08:43:32 +00004325 : length_(length),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004326 raw_running_hash_(seed),
ager@chromium.org7c537e22008-10-16 08:43:32 +00004327 array_index_(0),
4328 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4329 is_first_char_(true),
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004330 is_valid_(true) {
4331 ASSERT(FLAG_randomize_string_hashes || raw_running_hash_ == 0);
4332}
ager@chromium.org7c537e22008-10-16 08:43:32 +00004333
4334
4335bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004336 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004337}
4338
4339
4340void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004341 // Use the Jenkins one-at-a-time hash function to update the hash
4342 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004343 raw_running_hash_ += c;
4344 raw_running_hash_ += (raw_running_hash_ << 10);
4345 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004346 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004347 if (is_array_index_) {
4348 if (c < '0' || c > '9') {
4349 is_array_index_ = false;
4350 } else {
4351 int d = c - '0';
4352 if (is_first_char_) {
4353 is_first_char_ = false;
4354 if (c == '0' && length_ > 1) {
4355 is_array_index_ = false;
4356 return;
4357 }
4358 }
4359 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4360 is_array_index_ = false;
4361 } else {
4362 array_index_ = array_index_ * 10 + d;
4363 }
4364 }
4365 }
4366}
4367
4368
4369void StringHasher::AddCharacterNoIndex(uc32 c) {
4370 ASSERT(!is_array_index());
4371 raw_running_hash_ += c;
4372 raw_running_hash_ += (raw_running_hash_ << 10);
4373 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4374}
4375
4376
4377uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004378 // Get the calculated raw hash value and do some more bit ops to distribute
4379 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004380 uint32_t result = raw_running_hash_;
4381 result += (result << 3);
4382 result ^= (result >> 11);
4383 result += (result << 15);
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004384 if ((result & String::kHashBitMask) == 0) {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004385 result = 27;
4386 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004387 return result;
4388}
4389
4390
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004391template <typename schar>
rossberg@chromium.orgfab14982012-01-05 15:02:15 +00004392uint32_t HashSequentialString(const schar* chars, int length, uint32_t seed) {
4393 StringHasher hasher(length, seed);
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004394 if (!hasher.has_trivial_hash()) {
4395 int i;
4396 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4397 hasher.AddCharacter(chars[i]);
4398 }
4399 for (; i < length; i++) {
4400 hasher.AddCharacterNoIndex(chars[i]);
4401 }
4402 }
4403 return hasher.GetHashField();
4404}
4405
4406
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004407bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004408 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004409 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4410 return false;
4411 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004412 return SlowAsArrayIndex(index);
4413}
4414
4415
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004416Object* JSReceiver::GetPrototype() {
4417 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004418}
4419
4420
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004421bool JSReceiver::HasProperty(String* name) {
4422 if (IsJSProxy()) {
4423 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4424 }
4425 return GetPropertyAttribute(name) != ABSENT;
4426}
4427
4428
4429bool JSReceiver::HasLocalProperty(String* name) {
4430 if (IsJSProxy()) {
4431 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4432 }
4433 return GetLocalPropertyAttribute(name) != ABSENT;
4434}
4435
4436
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004437PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004438 return GetPropertyAttributeWithReceiver(this, key);
4439}
4440
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004441// TODO(504): this may be useful in other places too where JSGlobalProxy
4442// is used.
4443Object* JSObject::BypassGlobalProxy() {
4444 if (IsJSGlobalProxy()) {
4445 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004446 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004447 ASSERT(proto->IsJSGlobalObject());
4448 return proto;
4449 }
4450 return this;
4451}
4452
4453
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004454MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4455 return IsJSProxy()
4456 ? JSProxy::cast(this)->GetIdentityHash(flag)
4457 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004458}
4459
4460
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004461bool JSReceiver::HasElement(uint32_t index) {
4462 if (IsJSProxy()) {
4463 return JSProxy::cast(this)->HasElementWithHandler(index);
4464 }
4465 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004466}
4467
4468
4469bool AccessorInfo::all_can_read() {
4470 return BooleanBit::get(flag(), kAllCanReadBit);
4471}
4472
4473
4474void AccessorInfo::set_all_can_read(bool value) {
4475 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4476}
4477
4478
4479bool AccessorInfo::all_can_write() {
4480 return BooleanBit::get(flag(), kAllCanWriteBit);
4481}
4482
4483
4484void AccessorInfo::set_all_can_write(bool value) {
4485 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4486}
4487
4488
ager@chromium.org870a0b62008-11-04 11:43:05 +00004489bool AccessorInfo::prohibits_overwriting() {
4490 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4491}
4492
4493
4494void AccessorInfo::set_prohibits_overwriting(bool value) {
4495 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4496}
4497
4498
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004499PropertyAttributes AccessorInfo::property_attributes() {
4500 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4501}
4502
4503
4504void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004505 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004506}
4507
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004508
4509template<typename Shape, typename Key>
4510void Dictionary<Shape, Key>::SetEntry(int entry,
4511 Object* key,
4512 Object* value) {
4513 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4514}
4515
4516
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004517template<typename Shape, typename Key>
4518void Dictionary<Shape, Key>::SetEntry(int entry,
4519 Object* key,
4520 Object* value,
4521 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004522 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004523 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004524 AssertNoAllocation no_gc;
4525 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004526 FixedArray::set(index, key, mode);
4527 FixedArray::set(index+1, value, mode);
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004528 FixedArray::set(index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004529}
4530
4531
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004532bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4533 ASSERT(other->IsNumber());
4534 return key == static_cast<uint32_t>(other->Number());
4535}
4536
4537
4538uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4539 return ComputeIntegerHash(key);
4540}
4541
4542
4543uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4544 ASSERT(other->IsNumber());
4545 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4546}
4547
4548
4549MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4550 return Isolate::Current()->heap()->NumberFromUint32(key);
4551}
4552
4553
4554bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4555 // We know that all entries in a hash table had their hash keys created.
4556 // Use that knowledge to have fast failure.
4557 if (key->Hash() != String::cast(other)->Hash()) return false;
4558 return key->Equals(String::cast(other));
4559}
4560
4561
4562uint32_t StringDictionaryShape::Hash(String* key) {
4563 return key->Hash();
4564}
4565
4566
4567uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4568 return String::cast(other)->Hash();
4569}
4570
4571
4572MaybeObject* StringDictionaryShape::AsObject(String* key) {
4573 return key;
4574}
4575
4576
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004577template <int entrysize>
4578bool ObjectHashTableShape<entrysize>::IsMatch(Object* key, Object* other) {
4579 return key->SameValue(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004580}
4581
4582
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004583template <int entrysize>
4584uint32_t ObjectHashTableShape<entrysize>::Hash(Object* key) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004585 MaybeObject* maybe_hash = key->GetHash(OMIT_CREATION);
4586 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004587}
4588
4589
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004590template <int entrysize>
4591uint32_t ObjectHashTableShape<entrysize>::HashForObject(Object* key,
4592 Object* other) {
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004593 MaybeObject* maybe_hash = other->GetHash(OMIT_CREATION);
4594 return Smi::cast(maybe_hash->ToObjectChecked())->value();
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004595}
4596
4597
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004598template <int entrysize>
4599MaybeObject* ObjectHashTableShape<entrysize>::AsObject(Object* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004600 return key;
4601}
4602
4603
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004604void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004605 // No write barrier is needed since empty_fixed_array is not in new space.
4606 // Please note this function is used during marking:
4607 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004608 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4609 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004610}
4611
4612
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004613void JSArray::EnsureSize(int required_size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004614 ASSERT(HasFastTypeElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004615 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004616 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4617 if (elts->length() < required_size) {
4618 // Doubling in size would be overkill, but leave some slack to avoid
4619 // constantly growing.
4620 Expand(required_size + (required_size >> 3));
4621 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004622 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004623 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4624 // Expand will allocate a new backing store in new space even if the size
4625 // we asked for isn't larger than what we had before.
4626 Expand(required_size);
4627 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004628}
4629
4630
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004631void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004632 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004633 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4634}
4635
4636
ricow@chromium.org7ad65222011-12-19 12:13:11 +00004637bool JSArray::AllowsSetElementsLength() {
4638 bool result = elements()->IsFixedArray() || elements()->IsFixedDoubleArray();
4639 ASSERT(result == !HasExternalArrayElements());
4640 return result;
4641}
4642
4643
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004644MaybeObject* JSArray::SetContent(FixedArrayBase* storage) {
4645 MaybeObject* maybe_result = EnsureCanContainElements(
4646 storage, ALLOW_COPIED_DOUBLE_ELEMENTS);
4647 if (maybe_result->IsFailure()) return maybe_result;
4648 ASSERT((storage->map() == GetHeap()->fixed_double_array_map() &&
4649 GetElementsKind() == FAST_DOUBLE_ELEMENTS) ||
4650 ((storage->map() != GetHeap()->fixed_double_array_map()) &&
4651 ((GetElementsKind() == FAST_ELEMENTS) ||
4652 (GetElementsKind() == FAST_SMI_ONLY_ELEMENTS &&
4653 FixedArray::cast(storage)->ContainsOnlySmisOrHoles()))));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004654 set_elements(storage);
ricow@chromium.org64e3a4b2011-12-13 08:07:27 +00004655 set_length(Smi::FromInt(storage->length()));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004656 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004657}
4658
4659
lrn@chromium.org303ada72010-10-27 09:33:13 +00004660MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004661 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004662 return GetHeap()->CopyFixedArray(this);
4663}
4664
4665
erik.corry@gmail.com394dbcf2011-10-27 07:38:48 +00004666MaybeObject* FixedDoubleArray::Copy() {
4667 if (length() == 0) return this;
4668 return GetHeap()->CopyFixedDoubleArray(this);
4669}
4670
4671
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004672Relocatable::Relocatable(Isolate* isolate) {
4673 ASSERT(isolate == Isolate::Current());
4674 isolate_ = isolate;
4675 prev_ = isolate->relocatable_top();
4676 isolate->set_relocatable_top(this);
4677}
4678
4679
4680Relocatable::~Relocatable() {
4681 ASSERT(isolate_ == Isolate::Current());
4682 ASSERT_EQ(isolate_->relocatable_top(), this);
4683 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004684}
4685
4686
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004687int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4688 return map->instance_size();
4689}
4690
4691
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004692void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004693 v->VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004694 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004695}
4696
4697
4698template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004699void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004700 StaticVisitor::VisitExternalReference(
jkummerow@chromium.orgc3b37122011-11-07 10:14:12 +00004701 reinterpret_cast<Address*>(FIELD_ADDR(this, kForeignAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004702}
4703
4704
4705void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4706 typedef v8::String::ExternalAsciiStringResource Resource;
4707 v->VisitExternalAsciiString(
4708 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4709}
4710
4711
4712template<typename StaticVisitor>
4713void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4714 typedef v8::String::ExternalAsciiStringResource Resource;
4715 StaticVisitor::VisitExternalAsciiString(
4716 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4717}
4718
4719
4720void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4721 typedef v8::String::ExternalStringResource Resource;
4722 v->VisitExternalTwoByteString(
4723 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4724}
4725
4726
4727template<typename StaticVisitor>
4728void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4729 typedef v8::String::ExternalStringResource Resource;
4730 StaticVisitor::VisitExternalTwoByteString(
4731 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4732}
4733
4734#define SLOT_ADDR(obj, offset) \
4735 reinterpret_cast<Object**>((obj)->address() + offset)
4736
4737template<int start_offset, int end_offset, int size>
4738void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4739 HeapObject* obj,
4740 ObjectVisitor* v) {
4741 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4742}
4743
4744
4745template<int start_offset>
4746void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4747 int object_size,
4748 ObjectVisitor* v) {
4749 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4750}
4751
4752#undef SLOT_ADDR
4753
4754
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004755#undef CAST_ACCESSOR
4756#undef INT_ACCESSORS
4757#undef SMI_ACCESSORS
4758#undef ACCESSORS
4759#undef FIELD_ADDR
4760#undef READ_FIELD
4761#undef WRITE_FIELD
4762#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004763#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004764#undef READ_MEMADDR_FIELD
4765#undef WRITE_MEMADDR_FIELD
4766#undef READ_DOUBLE_FIELD
4767#undef WRITE_DOUBLE_FIELD
4768#undef READ_INT_FIELD
4769#undef WRITE_INT_FIELD
4770#undef READ_SHORT_FIELD
4771#undef WRITE_SHORT_FIELD
4772#undef READ_BYTE_FIELD
4773#undef WRITE_BYTE_FIELD
4774
4775
4776} } // namespace v8::internal
4777
4778#endif // V8_OBJECTS_INL_H_