blob: 6d7bad751210ef2855ea8031c5f197684077f074 [file] [log] [blame]
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001// Copyright 2006-2008 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
38#include "objects.h"
39#include "contexts.h"
40#include "conversions-inl.h"
41#include "property.h"
42
kasperl@chromium.org71affb52009-05-26 05:44:31 +000043namespace v8 {
44namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000045
46PropertyDetails::PropertyDetails(Smi* smi) {
47 value_ = smi->value();
48}
49
50
51Smi* PropertyDetails::AsSmi() {
52 return Smi::FromInt(value_);
53}
54
55
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000056PropertyDetails PropertyDetails::AsDeleted() {
57 PropertyDetails d(DONT_ENUM, NORMAL);
58 Smi* smi = Smi::FromInt(AsSmi()->value() | DeletedField::encode(1));
59 return PropertyDetails(smi);
60}
61
62
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000063#define CAST_ACCESSOR(type) \
64 type* type::cast(Object* object) { \
65 ASSERT(object->Is##type()); \
66 return reinterpret_cast<type*>(object); \
67 }
68
69
70#define INT_ACCESSORS(holder, name, offset) \
71 int holder::name() { return READ_INT_FIELD(this, offset); } \
72 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
73
74
75#define ACCESSORS(holder, name, type, offset) \
76 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000077 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000078 WRITE_FIELD(this, offset, value); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000079 CONDITIONAL_WRITE_BARRIER(this, offset, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000080 }
81
82
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000083
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000084#define SMI_ACCESSORS(holder, name, offset) \
85 int holder::name() { \
86 Object* value = READ_FIELD(this, offset); \
87 return Smi::cast(value)->value(); \
88 } \
89 void holder::set_##name(int value) { \
90 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
91 }
92
93
sgjesse@chromium.org911335c2009-08-19 12:59:44 +000094#define BOOL_GETTER(holder, field, name, offset) \
95 bool holder::name() { \
96 return BooleanBit::get(field(), offset); \
97 } \
98
99
100#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000101 bool holder::name() { \
102 return BooleanBit::get(field(), offset); \
103 } \
104 void holder::set_##name(bool value) { \
105 set_##field(BooleanBit::set(field(), offset, value)); \
106 }
107
108
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000109bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
110 // There is a constraint on the object; check.
111 if (!this->IsJSObject()) return false;
112 // Fetch the constructor function of the object.
113 Object* cons_obj = JSObject::cast(this)->map()->constructor();
114 if (!cons_obj->IsJSFunction()) return false;
115 JSFunction* fun = JSFunction::cast(cons_obj);
116 // Iterate through the chain of inheriting function templates to
117 // see if the required one occurs.
118 for (Object* type = fun->shared()->function_data();
119 type->IsFunctionTemplateInfo();
120 type = FunctionTemplateInfo::cast(type)->parent_template()) {
121 if (type == expected) return true;
122 }
123 // Didn't find the required type in the inheritance chain.
124 return false;
125}
126
127
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000128bool Object::IsSmi() {
129 return HAS_SMI_TAG(this);
130}
131
132
133bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000134 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000135}
136
137
138bool Object::IsHeapNumber() {
139 return Object::IsHeapObject()
140 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE;
141}
142
143
144bool Object::IsString() {
145 return Object::IsHeapObject()
146 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
147}
148
149
ager@chromium.org870a0b62008-11-04 11:43:05 +0000150bool Object::IsSymbol() {
151 if (!this->IsHeapObject()) return false;
152 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000153 // Because the symbol tag is non-zero and no non-string types have the
154 // symbol bit set we can test for symbols with a very simple test
155 // operation.
156 ASSERT(kSymbolTag != 0);
157 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
158 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000159}
160
161
162bool Object::IsConsString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000163 if (!this->IsHeapObject()) return false;
164 uint32_t type = HeapObject::cast(this)->map()->instance_type();
165 return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
166 (kStringTag | kConsStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000167}
168
169
ager@chromium.org870a0b62008-11-04 11:43:05 +0000170bool Object::IsSeqString() {
171 if (!IsString()) return false;
172 return StringShape(String::cast(this)).IsSequential();
173}
174
175
176bool Object::IsSeqAsciiString() {
177 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000178 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000179 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000180}
181
182
183bool Object::IsSeqTwoByteString() {
184 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000185 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000186 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000187}
188
189
190bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000191 if (!IsString()) return false;
192 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000193}
194
195
196bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000197 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000198 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000199 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000200}
201
202
203bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000204 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000205 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000206 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000207}
208
209
ager@chromium.org870a0b62008-11-04 11:43:05 +0000210StringShape::StringShape(String* str)
211 : type_(str->map()->instance_type()) {
212 set_valid();
213 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000214}
215
216
ager@chromium.org870a0b62008-11-04 11:43:05 +0000217StringShape::StringShape(Map* map)
218 : type_(map->instance_type()) {
219 set_valid();
220 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000221}
222
223
ager@chromium.org870a0b62008-11-04 11:43:05 +0000224StringShape::StringShape(InstanceType t)
225 : type_(static_cast<uint32_t>(t)) {
226 set_valid();
227 ASSERT((type_ & kIsNotStringMask) == kStringTag);
228}
229
230
231bool StringShape::IsSymbol() {
232 ASSERT(valid());
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000233 ASSERT(kSymbolTag != 0);
234 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000235}
236
237
ager@chromium.org5ec48922009-05-05 07:25:34 +0000238bool String::IsAsciiRepresentation() {
239 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000240 if ((type & kStringRepresentationMask) == kConsStringTag &&
241 ConsString::cast(this)->second()->length() == 0) {
242 return ConsString::cast(this)->first()->IsAsciiRepresentation();
243 }
244 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000245}
246
247
ager@chromium.org5ec48922009-05-05 07:25:34 +0000248bool String::IsTwoByteRepresentation() {
249 uint32_t type = map()->instance_type();
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000250 if ((type & kStringRepresentationMask) == kConsStringTag &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000251 ConsString::cast(this)->second()->length() == 0) {
252 return ConsString::cast(this)->first()->IsTwoByteRepresentation();
253 }
254 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000255}
256
257
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000258bool String::IsExternalTwoByteStringWithAsciiChars() {
259 if (!IsExternalTwoByteString()) return false;
260 const uc16* data = ExternalTwoByteString::cast(this)->resource()->data();
261 for (int i = 0, len = length(); i < len; i++) {
262 if (data[i] > kMaxAsciiCharCode) return false;
263 }
264 return true;
265}
266
267
ager@chromium.org870a0b62008-11-04 11:43:05 +0000268bool StringShape::IsCons() {
269 return (type_ & kStringRepresentationMask) == kConsStringTag;
270}
271
272
ager@chromium.org870a0b62008-11-04 11:43:05 +0000273bool StringShape::IsExternal() {
274 return (type_ & kStringRepresentationMask) == kExternalStringTag;
275}
276
277
278bool StringShape::IsSequential() {
279 return (type_ & kStringRepresentationMask) == kSeqStringTag;
280}
281
282
283StringRepresentationTag StringShape::representation_tag() {
284 uint32_t tag = (type_ & kStringRepresentationMask);
285 return static_cast<StringRepresentationTag>(tag);
286}
287
288
289uint32_t StringShape::full_representation_tag() {
290 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
291}
292
293
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000294STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
295 Internals::kFullStringRepresentationMask);
296
297
ager@chromium.org870a0b62008-11-04 11:43:05 +0000298bool StringShape::IsSequentialAscii() {
299 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
300}
301
302
303bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000304 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000305}
306
307
308bool StringShape::IsExternalAscii() {
309 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
310}
311
312
313bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000314 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000315}
316
317
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000318STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
319 Internals::kExternalTwoByteRepresentationTag);
320
321
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000322uc32 FlatStringReader::Get(int index) {
323 ASSERT(0 <= index && index <= length_);
324 if (is_ascii_) {
325 return static_cast<const byte*>(start_)[index];
326 } else {
327 return static_cast<const uc16*>(start_)[index];
328 }
329}
330
331
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000332bool Object::IsNumber() {
333 return IsSmi() || IsHeapNumber();
334}
335
336
337bool Object::IsByteArray() {
338 return Object::IsHeapObject()
339 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
340}
341
342
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000343bool Object::IsPixelArray() {
344 return Object::IsHeapObject() &&
345 HeapObject::cast(this)->map()->instance_type() == PIXEL_ARRAY_TYPE;
346}
347
348
ager@chromium.org3811b432009-10-28 14:53:37 +0000349bool Object::IsExternalArray() {
350 if (!Object::IsHeapObject())
351 return false;
352 InstanceType instance_type =
353 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000354 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
355 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000356}
357
358
359bool Object::IsExternalByteArray() {
360 return Object::IsHeapObject() &&
361 HeapObject::cast(this)->map()->instance_type() ==
362 EXTERNAL_BYTE_ARRAY_TYPE;
363}
364
365
366bool Object::IsExternalUnsignedByteArray() {
367 return Object::IsHeapObject() &&
368 HeapObject::cast(this)->map()->instance_type() ==
369 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
370}
371
372
373bool Object::IsExternalShortArray() {
374 return Object::IsHeapObject() &&
375 HeapObject::cast(this)->map()->instance_type() ==
376 EXTERNAL_SHORT_ARRAY_TYPE;
377}
378
379
380bool Object::IsExternalUnsignedShortArray() {
381 return Object::IsHeapObject() &&
382 HeapObject::cast(this)->map()->instance_type() ==
383 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
384}
385
386
387bool Object::IsExternalIntArray() {
388 return Object::IsHeapObject() &&
389 HeapObject::cast(this)->map()->instance_type() ==
390 EXTERNAL_INT_ARRAY_TYPE;
391}
392
393
394bool Object::IsExternalUnsignedIntArray() {
395 return Object::IsHeapObject() &&
396 HeapObject::cast(this)->map()->instance_type() ==
397 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
398}
399
400
401bool Object::IsExternalFloatArray() {
402 return Object::IsHeapObject() &&
403 HeapObject::cast(this)->map()->instance_type() ==
404 EXTERNAL_FLOAT_ARRAY_TYPE;
405}
406
407
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000408bool Object::IsFailure() {
409 return HAS_FAILURE_TAG(this);
410}
411
412
413bool Object::IsRetryAfterGC() {
414 return HAS_FAILURE_TAG(this)
415 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
416}
417
418
ager@chromium.org7c537e22008-10-16 08:43:32 +0000419bool Object::IsOutOfMemoryFailure() {
420 return HAS_FAILURE_TAG(this)
421 && Failure::cast(this)->IsOutOfMemoryException();
422}
423
424
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000425bool Object::IsException() {
426 return this == Failure::Exception();
427}
428
429
430bool Object::IsJSObject() {
431 return IsHeapObject()
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000432 && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000433}
434
435
ager@chromium.org32912102009-01-16 10:38:43 +0000436bool Object::IsJSContextExtensionObject() {
437 return IsHeapObject()
438 && (HeapObject::cast(this)->map()->instance_type() ==
439 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
440}
441
442
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000443bool Object::IsMap() {
444 return Object::IsHeapObject()
445 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
446}
447
448
449bool Object::IsFixedArray() {
450 return Object::IsHeapObject()
451 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
452}
453
454
455bool Object::IsDescriptorArray() {
456 return IsFixedArray();
457}
458
459
460bool Object::IsContext() {
461 return Object::IsHeapObject()
462 && (HeapObject::cast(this)->map() == Heap::context_map() ||
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000463 HeapObject::cast(this)->map() == Heap::catch_context_map() ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000464 HeapObject::cast(this)->map() == Heap::global_context_map());
465}
466
467
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000468bool Object::IsCatchContext() {
469 return Object::IsHeapObject()
470 && HeapObject::cast(this)->map() == Heap::catch_context_map();
471}
472
473
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000474bool Object::IsGlobalContext() {
475 return Object::IsHeapObject()
476 && HeapObject::cast(this)->map() == Heap::global_context_map();
477}
478
479
480bool Object::IsJSFunction() {
481 return Object::IsHeapObject()
482 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
483}
484
485
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000486template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000487 return obj->IsJSFunction();
488}
489
490
491bool Object::IsCode() {
492 return Object::IsHeapObject()
493 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
494}
495
496
497bool Object::IsOddball() {
498 return Object::IsHeapObject()
499 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
500}
501
502
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000503bool Object::IsJSGlobalPropertyCell() {
504 return Object::IsHeapObject()
505 && HeapObject::cast(this)->map()->instance_type()
506 == JS_GLOBAL_PROPERTY_CELL_TYPE;
507}
508
509
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000510bool Object::IsSharedFunctionInfo() {
511 return Object::IsHeapObject() &&
512 (HeapObject::cast(this)->map()->instance_type() ==
513 SHARED_FUNCTION_INFO_TYPE);
514}
515
516
517bool Object::IsJSValue() {
518 return Object::IsHeapObject()
519 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
520}
521
522
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000523bool Object::IsStringWrapper() {
524 return IsJSValue() && JSValue::cast(this)->value()->IsString();
525}
526
527
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000528bool Object::IsProxy() {
529 return Object::IsHeapObject()
530 && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
531}
532
533
534bool Object::IsBoolean() {
535 return IsTrue() || IsFalse();
536}
537
538
539bool Object::IsJSArray() {
540 return Object::IsHeapObject()
541 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
542}
543
544
ager@chromium.org236ad962008-09-25 09:45:57 +0000545bool Object::IsJSRegExp() {
546 return Object::IsHeapObject()
547 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
548}
549
550
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000551template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000552 return obj->IsJSArray();
553}
554
555
556bool Object::IsHashTable() {
557 return Object::IsHeapObject()
558 && HeapObject::cast(this)->map() == Heap::hash_table_map();
559}
560
561
562bool Object::IsDictionary() {
563 return IsHashTable() && this != Heap::symbol_table();
564}
565
566
567bool Object::IsSymbolTable() {
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000568 return IsHashTable() && this == Heap::raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000569}
570
571
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000572bool Object::IsCompilationCacheTable() {
573 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000574}
575
576
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000577bool Object::IsCodeCacheHashTable() {
578 return IsHashTable();
579}
580
581
ager@chromium.org236ad962008-09-25 09:45:57 +0000582bool Object::IsMapCache() {
583 return IsHashTable();
584}
585
586
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000587bool Object::IsPrimitive() {
588 return IsOddball() || IsNumber() || IsString();
589}
590
591
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000592bool Object::IsJSGlobalProxy() {
593 bool result = IsHeapObject() &&
594 (HeapObject::cast(this)->map()->instance_type() ==
595 JS_GLOBAL_PROXY_TYPE);
596 ASSERT(!result || IsAccessCheckNeeded());
597 return result;
598}
599
600
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000601bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000602 if (!IsHeapObject()) return false;
603
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000604 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000605 return type == JS_GLOBAL_OBJECT_TYPE ||
606 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000607}
608
609
610bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000611 return IsHeapObject() &&
612 (HeapObject::cast(this)->map()->instance_type() ==
613 JS_GLOBAL_OBJECT_TYPE);
614}
615
616
617bool Object::IsJSBuiltinsObject() {
618 return IsHeapObject() &&
619 (HeapObject::cast(this)->map()->instance_type() ==
620 JS_BUILTINS_OBJECT_TYPE);
621}
622
623
624bool Object::IsUndetectableObject() {
625 return IsHeapObject()
626 && HeapObject::cast(this)->map()->is_undetectable();
627}
628
629
630bool Object::IsAccessCheckNeeded() {
631 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000632 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000633}
634
635
636bool Object::IsStruct() {
637 if (!IsHeapObject()) return false;
638 switch (HeapObject::cast(this)->map()->instance_type()) {
639#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
640 STRUCT_LIST(MAKE_STRUCT_CASE)
641#undef MAKE_STRUCT_CASE
642 default: return false;
643 }
644}
645
646
647#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
648 bool Object::Is##Name() { \
649 return Object::IsHeapObject() \
650 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
651 }
652 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
653#undef MAKE_STRUCT_PREDICATE
654
655
656bool Object::IsUndefined() {
657 return this == Heap::undefined_value();
658}
659
660
661bool Object::IsTheHole() {
662 return this == Heap::the_hole_value();
663}
664
665
666bool Object::IsNull() {
667 return this == Heap::null_value();
668}
669
670
671bool Object::IsTrue() {
672 return this == Heap::true_value();
673}
674
675
676bool Object::IsFalse() {
677 return this == Heap::false_value();
678}
679
680
681double Object::Number() {
682 ASSERT(IsNumber());
683 return IsSmi()
684 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
685 : reinterpret_cast<HeapNumber*>(this)->value();
686}
687
688
689
690Object* Object::ToSmi() {
691 if (IsSmi()) return this;
692 if (IsHeapNumber()) {
693 double value = HeapNumber::cast(this)->value();
694 int int_value = FastD2I(value);
695 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
696 return Smi::FromInt(int_value);
697 }
698 }
699 return Failure::Exception();
700}
701
702
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000703bool Object::HasSpecificClassOf(String* name) {
704 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
705}
706
707
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000708Object* Object::GetElement(uint32_t index) {
709 return GetElementWithReceiver(this, index);
710}
711
712
713Object* Object::GetProperty(String* key) {
714 PropertyAttributes attributes;
715 return GetPropertyWithReceiver(this, key, &attributes);
716}
717
718
719Object* Object::GetProperty(String* key, PropertyAttributes* attributes) {
720 return GetPropertyWithReceiver(this, key, attributes);
721}
722
723
724#define FIELD_ADDR(p, offset) \
725 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
726
727#define READ_FIELD(p, offset) \
728 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
729
730#define WRITE_FIELD(p, offset, value) \
731 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
732
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000733
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000734#define WRITE_BARRIER(object, offset) \
735 Heap::RecordWrite(object->address(), offset);
736
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000737// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000738// write due to the assert validating the written value.
739#define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \
740 if (mode == UPDATE_WRITE_BARRIER) { \
741 Heap::RecordWrite(object->address(), offset); \
742 } else { \
743 ASSERT(mode == SKIP_WRITE_BARRIER); \
744 ASSERT(Heap::InNewSpace(object) || \
745 !Heap::InNewSpace(READ_FIELD(object, offset))); \
746 }
747
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000748#define READ_DOUBLE_FIELD(p, offset) \
749 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
750
751#define WRITE_DOUBLE_FIELD(p, offset, value) \
752 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
753
754#define READ_INT_FIELD(p, offset) \
755 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
756
757#define WRITE_INT_FIELD(p, offset, value) \
758 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
759
ager@chromium.org3e875802009-06-29 08:26:34 +0000760#define READ_INTPTR_FIELD(p, offset) \
761 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
762
763#define WRITE_INTPTR_FIELD(p, offset, value) \
764 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
765
ager@chromium.org7c537e22008-10-16 08:43:32 +0000766#define READ_UINT32_FIELD(p, offset) \
767 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
768
769#define WRITE_UINT32_FIELD(p, offset, value) \
770 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
771
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000772#define READ_SHORT_FIELD(p, offset) \
773 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
774
775#define WRITE_SHORT_FIELD(p, offset, value) \
776 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
777
778#define READ_BYTE_FIELD(p, offset) \
779 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
780
781#define WRITE_BYTE_FIELD(p, offset, value) \
782 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
783
784
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000785Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
786 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000787}
788
789
790int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000791 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000792}
793
794
795Smi* Smi::FromInt(int value) {
796 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000797 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000798 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000799 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000800 return reinterpret_cast<Smi*>(tagged_value);
801}
802
803
804Smi* Smi::FromIntptr(intptr_t value) {
805 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000806 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
807 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000808}
809
810
811Failure::Type Failure::type() const {
812 return static_cast<Type>(value() & kFailureTypeTagMask);
813}
814
815
816bool Failure::IsInternalError() const {
817 return type() == INTERNAL_ERROR;
818}
819
820
821bool Failure::IsOutOfMemoryException() const {
822 return type() == OUT_OF_MEMORY_EXCEPTION;
823}
824
825
826int Failure::requested() const {
827 const int kShiftBits =
828 kFailureTypeTagSize + kSpaceTagSize - kObjectAlignmentBits;
829 STATIC_ASSERT(kShiftBits >= 0);
830 ASSERT(type() == RETRY_AFTER_GC);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000831 return static_cast<int>(value() >> kShiftBits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000832}
833
834
835AllocationSpace Failure::allocation_space() const {
836 ASSERT_EQ(RETRY_AFTER_GC, type());
837 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
838 & kSpaceTagMask);
839}
840
841
842Failure* Failure::InternalError() {
843 return Construct(INTERNAL_ERROR);
844}
845
846
847Failure* Failure::Exception() {
848 return Construct(EXCEPTION);
849}
850
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000851
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000852Failure* Failure::OutOfMemoryException() {
853 return Construct(OUT_OF_MEMORY_EXCEPTION);
854}
855
856
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000857intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000858 return static_cast<intptr_t>(
859 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000860}
861
862
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000863Failure* Failure::RetryAfterGC(int requested_bytes) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +0000864 // Assert that the space encoding fits in the three bytes allotted for it.
865 ASSERT((LAST_SPACE & ~kSpaceTagMask) == 0);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000866 uintptr_t requested =
867 static_cast<uintptr_t>(requested_bytes >> kObjectAlignmentBits);
868 int tag_bits = kSpaceTagSize + kFailureTypeTagSize + kFailureTagSize;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000869 if (((requested << tag_bits) >> tag_bits) != requested) {
870 // No room for entire requested size in the bits. Round down to
871 // maximally representable size.
872 requested = static_cast<intptr_t>(
873 (~static_cast<uintptr_t>(0)) >> (tag_bits + 1));
874 }
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000875 int value = static_cast<int>(requested << kSpaceTagSize) | NEW_SPACE;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000876 return Construct(RETRY_AFTER_GC, value);
877}
878
879
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000880Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000881 uintptr_t info =
882 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000883 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000884 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000885}
886
887
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000888bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000889#ifdef DEBUG
890 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
891#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000892
893#ifdef V8_TARGET_ARCH_X64
894 // To be representable as a long smi, the value must be a 32-bit integer.
895 bool result = (value == static_cast<int32_t>(value));
896#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000897 // To be representable as an tagged small integer, the two
898 // most-significant bits of 'value' must be either 00 or 11 due to
899 // sign-extension. To check this we add 01 to the two
900 // most-significant bits, and check if the most-significant bit is 0
901 //
902 // CAUTION: The original code below:
903 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
904 // may lead to incorrect results according to the C language spec, and
905 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
906 // compiler may produce undefined results in case of signed integer
907 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000908 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +0000909#endif
ager@chromium.org9085a012009-05-11 19:22:57 +0000910 ASSERT(result == in_range);
911 return result;
912}
913
914
kasper.lund7276f142008-07-30 08:49:36 +0000915MapWord MapWord::FromMap(Map* map) {
916 return MapWord(reinterpret_cast<uintptr_t>(map));
917}
918
919
920Map* MapWord::ToMap() {
921 return reinterpret_cast<Map*>(value_);
922}
923
924
925bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000926 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000927}
928
929
930MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000931 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
932 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000933}
934
935
936HeapObject* MapWord::ToForwardingAddress() {
937 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000938 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000939}
940
941
942bool MapWord::IsMarked() {
943 return (value_ & kMarkingMask) == 0;
944}
945
946
947void MapWord::SetMark() {
948 value_ &= ~kMarkingMask;
949}
950
951
952void MapWord::ClearMark() {
953 value_ |= kMarkingMask;
954}
955
956
957bool MapWord::IsOverflowed() {
958 return (value_ & kOverflowMask) != 0;
959}
960
961
962void MapWord::SetOverflow() {
963 value_ |= kOverflowMask;
964}
965
966
967void MapWord::ClearOverflow() {
968 value_ &= ~kOverflowMask;
969}
970
971
972MapWord MapWord::EncodeAddress(Address map_address, int offset) {
973 // Offset is the distance in live bytes from the first live object in the
974 // same page. The offset between two objects in the same page should not
975 // exceed the object area size of a page.
976 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
977
sgjesse@chromium.org846fb742009-12-18 08:56:33 +0000978 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +0000979 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
980
981 Page* map_page = Page::FromAddress(map_address);
982 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
983
sgjesse@chromium.org846fb742009-12-18 08:56:33 +0000984 uintptr_t map_page_offset =
985 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +0000986
987 uintptr_t encoding =
988 (compact_offset << kForwardingOffsetShift) |
989 (map_page_offset << kMapPageOffsetShift) |
990 (map_page->mc_page_index << kMapPageIndexShift);
991 return MapWord(encoding);
992}
993
994
995Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000996 int map_page_index =
997 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +0000998 ASSERT_MAP_PAGE_INDEX(map_page_index);
999
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001000 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001001 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1002 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001003
1004 return (map_space->PageAddress(map_page_index) + map_page_offset);
1005}
1006
1007
1008int MapWord::DecodeOffset() {
1009 // The offset field is represented in the kForwardingOffsetBits
1010 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001011 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1012 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1013 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001014}
1015
1016
1017MapWord MapWord::FromEncodedAddress(Address address) {
1018 return MapWord(reinterpret_cast<uintptr_t>(address));
1019}
1020
1021
1022Address MapWord::ToEncodedAddress() {
1023 return reinterpret_cast<Address>(value_);
1024}
1025
1026
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001027#ifdef DEBUG
1028void HeapObject::VerifyObjectField(int offset) {
1029 VerifyPointer(READ_FIELD(this, offset));
1030}
1031#endif
1032
1033
1034Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001035 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001036}
1037
1038
1039void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001040 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001041}
1042
1043
kasper.lund7276f142008-07-30 08:49:36 +00001044MapWord HeapObject::map_word() {
1045 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1046}
1047
1048
1049void HeapObject::set_map_word(MapWord map_word) {
1050 // WRITE_FIELD does not update the remembered set, but there is no need
1051 // here.
1052 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1053}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001054
1055
1056HeapObject* HeapObject::FromAddress(Address address) {
1057 ASSERT_TAG_ALIGNED(address);
1058 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1059}
1060
1061
1062Address HeapObject::address() {
1063 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1064}
1065
1066
1067int HeapObject::Size() {
1068 return SizeFromMap(map());
1069}
1070
1071
1072void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1073 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1074 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1075}
1076
1077
1078void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1079 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1080}
1081
1082
kasper.lund7276f142008-07-30 08:49:36 +00001083bool HeapObject::IsMarked() {
1084 return map_word().IsMarked();
1085}
1086
1087
1088void HeapObject::SetMark() {
1089 ASSERT(!IsMarked());
1090 MapWord first_word = map_word();
1091 first_word.SetMark();
1092 set_map_word(first_word);
1093}
1094
1095
1096void HeapObject::ClearMark() {
1097 ASSERT(IsMarked());
1098 MapWord first_word = map_word();
1099 first_word.ClearMark();
1100 set_map_word(first_word);
1101}
1102
1103
1104bool HeapObject::IsOverflowed() {
1105 return map_word().IsOverflowed();
1106}
1107
1108
1109void HeapObject::SetOverflow() {
1110 MapWord first_word = map_word();
1111 first_word.SetOverflow();
1112 set_map_word(first_word);
1113}
1114
1115
1116void HeapObject::ClearOverflow() {
1117 ASSERT(IsOverflowed());
1118 MapWord first_word = map_word();
1119 first_word.ClearOverflow();
1120 set_map_word(first_word);
1121}
1122
1123
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001124double HeapNumber::value() {
1125 return READ_DOUBLE_FIELD(this, kValueOffset);
1126}
1127
1128
1129void HeapNumber::set_value(double value) {
1130 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1131}
1132
1133
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001134int HeapNumber::get_exponent() {
1135 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1136 kExponentShift) - kExponentBias;
1137}
1138
1139
1140int HeapNumber::get_sign() {
1141 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1142}
1143
1144
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001145ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001146
1147
1148Array* JSObject::elements() {
1149 Object* array = READ_FIELD(this, kElementsOffset);
1150 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001151 ASSERT(array->IsFixedArray() || array->IsPixelArray() ||
1152 array->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001153 return reinterpret_cast<Array*>(array);
1154}
1155
1156
1157void JSObject::set_elements(Array* value, WriteBarrierMode mode) {
1158 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001159 ASSERT(value->IsFixedArray() || value->IsPixelArray() ||
1160 value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001161 WRITE_FIELD(this, kElementsOffset, value);
1162 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode);
1163}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001164
1165
1166void JSObject::initialize_properties() {
1167 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1168 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1169}
1170
1171
1172void JSObject::initialize_elements() {
1173 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1174 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1175}
1176
1177
1178ACCESSORS(Oddball, to_string, String, kToStringOffset)
1179ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1180
1181
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001182Object* JSGlobalPropertyCell::value() {
1183 return READ_FIELD(this, kValueOffset);
1184}
1185
1186
1187void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1188 // The write barrier is not used for global property cells.
1189 ASSERT(!val->IsJSGlobalPropertyCell());
1190 WRITE_FIELD(this, kValueOffset, val);
1191}
1192
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001193
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001194int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001195 InstanceType type = map()->instance_type();
1196 // Check for the most common kind of JavaScript object before
1197 // falling into the generic switch. This speeds up the internal
1198 // field operations considerably on average.
1199 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1200 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001201 case JS_GLOBAL_PROXY_TYPE:
1202 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001203 case JS_GLOBAL_OBJECT_TYPE:
1204 return JSGlobalObject::kSize;
1205 case JS_BUILTINS_OBJECT_TYPE:
1206 return JSBuiltinsObject::kSize;
1207 case JS_FUNCTION_TYPE:
1208 return JSFunction::kSize;
1209 case JS_VALUE_TYPE:
1210 return JSValue::kSize;
1211 case JS_ARRAY_TYPE:
1212 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001213 case JS_REGEXP_TYPE:
1214 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001215 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001216 return JSObject::kHeaderSize;
1217 default:
1218 UNREACHABLE();
1219 return 0;
1220 }
1221}
1222
1223
1224int JSObject::GetInternalFieldCount() {
1225 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001226 // Make sure to adjust for the number of in-object properties. These
1227 // properties do contribute to the size, but are not internal fields.
1228 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1229 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001230}
1231
1232
1233Object* JSObject::GetInternalField(int index) {
1234 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001235 // Internal objects do follow immediately after the header, whereas in-object
1236 // properties are at the end of the object. Therefore there is no need
1237 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001238 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1239}
1240
1241
1242void JSObject::SetInternalField(int index, Object* value) {
1243 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001244 // Internal objects do follow immediately after the header, whereas in-object
1245 // properties are at the end of the object. Therefore there is no need
1246 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001247 int offset = GetHeaderSize() + (kPointerSize * index);
1248 WRITE_FIELD(this, offset, value);
1249 WRITE_BARRIER(this, offset);
1250}
1251
1252
ager@chromium.org7c537e22008-10-16 08:43:32 +00001253// Access fast-case object properties at index. The use of these routines
1254// is needed to correctly distinguish between properties stored in-object and
1255// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001256Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001257 // Adjust for the number of properties stored in the object.
1258 index -= map()->inobject_properties();
1259 if (index < 0) {
1260 int offset = map()->instance_size() + (index * kPointerSize);
1261 return READ_FIELD(this, offset);
1262 } else {
1263 ASSERT(index < properties()->length());
1264 return properties()->get(index);
1265 }
1266}
1267
1268
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001269Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001270 // Adjust for the number of properties stored in the object.
1271 index -= map()->inobject_properties();
1272 if (index < 0) {
1273 int offset = map()->instance_size() + (index * kPointerSize);
1274 WRITE_FIELD(this, offset, value);
1275 WRITE_BARRIER(this, offset);
1276 } else {
1277 ASSERT(index < properties()->length());
1278 properties()->set(index, value);
1279 }
1280 return value;
1281}
1282
1283
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001284Object* JSObject::InObjectPropertyAt(int index) {
1285 // Adjust for the number of properties stored in the object.
1286 index -= map()->inobject_properties();
1287 ASSERT(index < 0);
1288 int offset = map()->instance_size() + (index * kPointerSize);
1289 return READ_FIELD(this, offset);
1290}
1291
1292
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001293Object* JSObject::InObjectPropertyAtPut(int index,
1294 Object* value,
1295 WriteBarrierMode mode) {
1296 // Adjust for the number of properties stored in the object.
1297 index -= map()->inobject_properties();
1298 ASSERT(index < 0);
1299 int offset = map()->instance_size() + (index * kPointerSize);
1300 WRITE_FIELD(this, offset, value);
1301 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1302 return value;
1303}
1304
1305
1306
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001307void JSObject::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001308 Object* value = Heap::undefined_value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001309 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001310 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001311 }
1312}
1313
1314
1315void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001316 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001317 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001318 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001319 }
1320}
1321
1322
1323bool JSObject::HasFastProperties() {
1324 return !properties()->IsDictionary();
1325}
1326
1327
1328bool Array::IndexFromObject(Object* object, uint32_t* index) {
1329 if (object->IsSmi()) {
1330 int value = Smi::cast(object)->value();
1331 if (value < 0) return false;
1332 *index = value;
1333 return true;
1334 }
1335 if (object->IsHeapNumber()) {
1336 double value = HeapNumber::cast(object)->value();
1337 uint32_t uint_value = static_cast<uint32_t>(value);
1338 if (value == static_cast<double>(uint_value)) {
1339 *index = uint_value;
1340 return true;
1341 }
1342 }
1343 return false;
1344}
1345
1346
1347bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1348 if (!this->IsJSValue()) return false;
1349
1350 JSValue* js_value = JSValue::cast(this);
1351 if (!js_value->value()->IsString()) return false;
1352
1353 String* str = String::cast(js_value->value());
1354 if (index >= (uint32_t)str->length()) return false;
1355
1356 return true;
1357}
1358
1359
1360Object* FixedArray::get(int index) {
1361 ASSERT(index >= 0 && index < this->length());
1362 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1363}
1364
1365
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001366void FixedArray::set(int index, Smi* value) {
1367 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1368 int offset = kHeaderSize + index * kPointerSize;
1369 WRITE_FIELD(this, offset, value);
1370}
1371
1372
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001373void FixedArray::set(int index, Object* value) {
1374 ASSERT(index >= 0 && index < this->length());
1375 int offset = kHeaderSize + index * kPointerSize;
1376 WRITE_FIELD(this, offset, value);
1377 WRITE_BARRIER(this, offset);
1378}
1379
1380
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001381WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001382 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1383 return UPDATE_WRITE_BARRIER;
1384}
1385
1386
1387void FixedArray::set(int index,
1388 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001389 WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001390 ASSERT(index >= 0 && index < this->length());
1391 int offset = kHeaderSize + index * kPointerSize;
1392 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001393 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001394}
1395
1396
1397void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
1398 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001399 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001400 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1401}
1402
1403
1404void FixedArray::set_undefined(int index) {
1405 ASSERT(index >= 0 && index < this->length());
1406 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1407 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1408 Heap::undefined_value());
1409}
1410
1411
ager@chromium.org236ad962008-09-25 09:45:57 +00001412void FixedArray::set_null(int index) {
1413 ASSERT(index >= 0 && index < this->length());
1414 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1415 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1416}
1417
1418
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001419void FixedArray::set_the_hole(int index) {
1420 ASSERT(index >= 0 && index < this->length());
1421 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1422 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1423}
1424
1425
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001426Object** FixedArray::data_start() {
1427 return HeapObject::RawField(this, kHeaderSize);
1428}
1429
1430
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001431bool DescriptorArray::IsEmpty() {
1432 ASSERT(this == Heap::empty_descriptor_array() ||
1433 this->length() > 2);
1434 return this == Heap::empty_descriptor_array();
1435}
1436
1437
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001438void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1439 Object* tmp = array->get(first);
1440 fast_set(array, first, array->get(second));
1441 fast_set(array, second, tmp);
1442}
1443
1444
1445int DescriptorArray::Search(String* name) {
1446 SLOW_ASSERT(IsSortedNoDuplicates());
1447
1448 // Check for empty descriptor array.
1449 int nof = number_of_descriptors();
1450 if (nof == 0) return kNotFound;
1451
1452 // Fast case: do linear search for small arrays.
1453 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001454 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001455 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001456 }
1457
1458 // Slow case: perform binary search.
1459 return BinarySearch(name, 0, nof - 1);
1460}
1461
1462
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001463String* DescriptorArray::GetKey(int descriptor_number) {
1464 ASSERT(descriptor_number < number_of_descriptors());
1465 return String::cast(get(ToKeyIndex(descriptor_number)));
1466}
1467
1468
1469Object* DescriptorArray::GetValue(int descriptor_number) {
1470 ASSERT(descriptor_number < number_of_descriptors());
1471 return GetContentArray()->get(ToValueIndex(descriptor_number));
1472}
1473
1474
1475Smi* DescriptorArray::GetDetails(int descriptor_number) {
1476 ASSERT(descriptor_number < number_of_descriptors());
1477 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1478}
1479
1480
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001481PropertyType DescriptorArray::GetType(int descriptor_number) {
1482 ASSERT(descriptor_number < number_of_descriptors());
1483 return PropertyDetails(GetDetails(descriptor_number)).type();
1484}
1485
1486
1487int DescriptorArray::GetFieldIndex(int descriptor_number) {
1488 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1489}
1490
1491
1492JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1493 return JSFunction::cast(GetValue(descriptor_number));
1494}
1495
1496
1497Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1498 ASSERT(GetType(descriptor_number) == CALLBACKS);
1499 return GetValue(descriptor_number);
1500}
1501
1502
1503AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1504 ASSERT(GetType(descriptor_number) == CALLBACKS);
1505 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1506 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1507}
1508
1509
1510bool DescriptorArray::IsProperty(int descriptor_number) {
1511 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1512}
1513
1514
1515bool DescriptorArray::IsTransition(int descriptor_number) {
1516 PropertyType t = GetType(descriptor_number);
1517 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
1518}
1519
1520
1521bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1522 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1523}
1524
1525
1526bool DescriptorArray::IsDontEnum(int descriptor_number) {
1527 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1528}
1529
1530
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001531void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1532 desc->Init(GetKey(descriptor_number),
1533 GetValue(descriptor_number),
1534 GetDetails(descriptor_number));
1535}
1536
1537
1538void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1539 // Range check.
1540 ASSERT(descriptor_number < number_of_descriptors());
1541
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001542 // Make sure none of the elements in desc are in new space.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001543 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1544 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1545
1546 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1547 FixedArray* content_array = GetContentArray();
1548 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1549 fast_set(content_array, ToDetailsIndex(descriptor_number),
1550 desc->GetDetails().AsSmi());
1551}
1552
1553
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001554void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1555 Descriptor desc;
1556 src->Get(src_index, &desc);
1557 Set(index, &desc);
1558}
1559
1560
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001561void DescriptorArray::Swap(int first, int second) {
1562 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1563 FixedArray* content_array = GetContentArray();
1564 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1565 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1566}
1567
1568
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001569bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001570 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001571 if (!max_index_object->IsSmi()) return false;
1572 return 0 !=
1573 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1574}
1575
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001576uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001577 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001578 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001579 if (!max_index_object->IsSmi()) return 0;
1580 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1581 return value >> kRequiresSlowElementsTagSize;
1582}
1583
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001584void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001585 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001586}
1587
1588
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001589// ------------------------------------
1590// Cast operations
1591
1592
1593CAST_ACCESSOR(FixedArray)
1594CAST_ACCESSOR(DescriptorArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001595CAST_ACCESSOR(SymbolTable)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001596CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001597CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001598CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001599CAST_ACCESSOR(String)
1600CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001601CAST_ACCESSOR(SeqAsciiString)
1602CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001603CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001604CAST_ACCESSOR(ExternalString)
1605CAST_ACCESSOR(ExternalAsciiString)
1606CAST_ACCESSOR(ExternalTwoByteString)
1607CAST_ACCESSOR(JSObject)
1608CAST_ACCESSOR(Smi)
1609CAST_ACCESSOR(Failure)
1610CAST_ACCESSOR(HeapObject)
1611CAST_ACCESSOR(HeapNumber)
1612CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001613CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001614CAST_ACCESSOR(SharedFunctionInfo)
1615CAST_ACCESSOR(Map)
1616CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001617CAST_ACCESSOR(GlobalObject)
1618CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001619CAST_ACCESSOR(JSGlobalObject)
1620CAST_ACCESSOR(JSBuiltinsObject)
1621CAST_ACCESSOR(Code)
1622CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001623CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001624CAST_ACCESSOR(Proxy)
1625CAST_ACCESSOR(ByteArray)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001626CAST_ACCESSOR(PixelArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001627CAST_ACCESSOR(ExternalArray)
1628CAST_ACCESSOR(ExternalByteArray)
1629CAST_ACCESSOR(ExternalUnsignedByteArray)
1630CAST_ACCESSOR(ExternalShortArray)
1631CAST_ACCESSOR(ExternalUnsignedShortArray)
1632CAST_ACCESSOR(ExternalIntArray)
1633CAST_ACCESSOR(ExternalUnsignedIntArray)
1634CAST_ACCESSOR(ExternalFloatArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001635CAST_ACCESSOR(Struct)
1636
1637
1638#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1639 STRUCT_LIST(MAKE_STRUCT_CAST)
1640#undef MAKE_STRUCT_CAST
1641
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001642
1643template <typename Shape, typename Key>
1644HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001645 ASSERT(obj->IsHashTable());
1646 return reinterpret_cast<HashTable*>(obj);
1647}
1648
1649
1650INT_ACCESSORS(Array, length, kLengthOffset)
1651
1652
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001653INT_ACCESSORS(String, length, kLengthOffset)
1654
1655
1656uint32_t String::hash_field() {
1657 return READ_UINT32_FIELD(this, kHashFieldOffset);
1658}
1659
1660
1661void String::set_hash_field(uint32_t value) {
1662 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
1663}
1664
1665
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001666bool String::Equals(String* other) {
1667 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001668 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1669 return false;
1670 }
1671 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001672}
1673
1674
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001675Object* String::TryFlatten(PretenureFlag pretenure) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001676 // We don't need to flatten strings that are already flat. Since this code
1677 // is inlined, it can be helpful in the flat case to not call out to Flatten.
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001678 if (IsFlat()) return this;
1679 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001680}
1681
1682
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001683uint16_t String::Get(int index) {
1684 ASSERT(index >= 0 && index < length());
1685 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001686 case kSeqStringTag | kAsciiStringTag:
1687 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1688 case kSeqStringTag | kTwoByteStringTag:
1689 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1690 case kConsStringTag | kAsciiStringTag:
1691 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001692 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001693 case kExternalStringTag | kAsciiStringTag:
1694 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1695 case kExternalStringTag | kTwoByteStringTag:
1696 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001697 default:
1698 break;
1699 }
1700
1701 UNREACHABLE();
1702 return 0;
1703}
1704
1705
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001706void String::Set(int index, uint16_t value) {
1707 ASSERT(index >= 0 && index < length());
1708 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001709
ager@chromium.org5ec48922009-05-05 07:25:34 +00001710 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001711 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1712 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001713}
1714
1715
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001716bool String::IsFlat() {
1717 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001718 case kConsStringTag: {
1719 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001720 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001721 return second->length() == 0;
1722 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001723 default:
1724 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001725 }
1726}
1727
1728
ager@chromium.org7c537e22008-10-16 08:43:32 +00001729uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001730 ASSERT(index >= 0 && index < length());
1731 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1732}
1733
1734
ager@chromium.org7c537e22008-10-16 08:43:32 +00001735void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001736 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1737 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1738 static_cast<byte>(value));
1739}
1740
1741
ager@chromium.org7c537e22008-10-16 08:43:32 +00001742Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001743 return FIELD_ADDR(this, kHeaderSize);
1744}
1745
1746
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001747char* SeqAsciiString::GetChars() {
1748 return reinterpret_cast<char*>(GetCharsAddress());
1749}
1750
1751
ager@chromium.org7c537e22008-10-16 08:43:32 +00001752Address SeqTwoByteString::GetCharsAddress() {
1753 return FIELD_ADDR(this, kHeaderSize);
1754}
1755
1756
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001757uc16* SeqTwoByteString::GetChars() {
1758 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1759}
1760
1761
ager@chromium.org7c537e22008-10-16 08:43:32 +00001762uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001763 ASSERT(index >= 0 && index < length());
1764 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1765}
1766
1767
ager@chromium.org7c537e22008-10-16 08:43:32 +00001768void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001769 ASSERT(index >= 0 && index < length());
1770 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1771}
1772
1773
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001774int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001775 uint32_t length = READ_INT_FIELD(this, kLengthOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001776 return SizeFor(length);
1777}
1778
1779
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001780int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001781 uint32_t length = READ_INT_FIELD(this, kLengthOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001782 return SizeFor(length);
1783}
1784
1785
ager@chromium.org870a0b62008-11-04 11:43:05 +00001786String* ConsString::first() {
1787 return String::cast(READ_FIELD(this, kFirstOffset));
1788}
1789
1790
1791Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001792 return READ_FIELD(this, kFirstOffset);
1793}
1794
1795
ager@chromium.org870a0b62008-11-04 11:43:05 +00001796void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001797 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001798 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001799}
1800
1801
ager@chromium.org870a0b62008-11-04 11:43:05 +00001802String* ConsString::second() {
1803 return String::cast(READ_FIELD(this, kSecondOffset));
1804}
1805
1806
1807Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001808 return READ_FIELD(this, kSecondOffset);
1809}
1810
1811
ager@chromium.org870a0b62008-11-04 11:43:05 +00001812void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001813 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001814 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001815}
1816
1817
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001818ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1819 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1820}
1821
1822
1823void ExternalAsciiString::set_resource(
1824 ExternalAsciiString::Resource* resource) {
1825 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1826}
1827
1828
1829ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1830 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1831}
1832
1833
1834void ExternalTwoByteString::set_resource(
1835 ExternalTwoByteString::Resource* resource) {
1836 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1837}
1838
1839
1840byte ByteArray::get(int index) {
1841 ASSERT(index >= 0 && index < this->length());
1842 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1843}
1844
1845
1846void ByteArray::set(int index, byte value) {
1847 ASSERT(index >= 0 && index < this->length());
1848 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
1849}
1850
1851
1852int ByteArray::get_int(int index) {
1853 ASSERT(index >= 0 && (index * kIntSize) < this->length());
1854 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
1855}
1856
1857
1858ByteArray* ByteArray::FromDataStartAddress(Address address) {
1859 ASSERT_TAG_ALIGNED(address);
1860 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
1861}
1862
1863
1864Address ByteArray::GetDataStartAddress() {
1865 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
1866}
1867
1868
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001869uint8_t* PixelArray::external_pointer() {
1870 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1871 return reinterpret_cast<uint8_t*>(ptr);
1872}
1873
1874
1875void PixelArray::set_external_pointer(uint8_t* value, WriteBarrierMode mode) {
1876 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1877 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1878}
1879
1880
1881uint8_t PixelArray::get(int index) {
1882 ASSERT((index >= 0) && (index < this->length()));
1883 uint8_t* ptr = external_pointer();
1884 return ptr[index];
1885}
1886
1887
1888void PixelArray::set(int index, uint8_t value) {
1889 ASSERT((index >= 0) && (index < this->length()));
1890 uint8_t* ptr = external_pointer();
1891 ptr[index] = value;
1892}
1893
1894
ager@chromium.org3811b432009-10-28 14:53:37 +00001895void* ExternalArray::external_pointer() {
1896 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1897 return reinterpret_cast<void*>(ptr);
1898}
1899
1900
1901void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
1902 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1903 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1904}
1905
1906
1907int8_t ExternalByteArray::get(int index) {
1908 ASSERT((index >= 0) && (index < this->length()));
1909 int8_t* ptr = static_cast<int8_t*>(external_pointer());
1910 return ptr[index];
1911}
1912
1913
1914void ExternalByteArray::set(int index, int8_t value) {
1915 ASSERT((index >= 0) && (index < this->length()));
1916 int8_t* ptr = static_cast<int8_t*>(external_pointer());
1917 ptr[index] = value;
1918}
1919
1920
1921uint8_t ExternalUnsignedByteArray::get(int index) {
1922 ASSERT((index >= 0) && (index < this->length()));
1923 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
1924 return ptr[index];
1925}
1926
1927
1928void ExternalUnsignedByteArray::set(int index, uint8_t value) {
1929 ASSERT((index >= 0) && (index < this->length()));
1930 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
1931 ptr[index] = value;
1932}
1933
1934
1935int16_t ExternalShortArray::get(int index) {
1936 ASSERT((index >= 0) && (index < this->length()));
1937 int16_t* ptr = static_cast<int16_t*>(external_pointer());
1938 return ptr[index];
1939}
1940
1941
1942void ExternalShortArray::set(int index, int16_t value) {
1943 ASSERT((index >= 0) && (index < this->length()));
1944 int16_t* ptr = static_cast<int16_t*>(external_pointer());
1945 ptr[index] = value;
1946}
1947
1948
1949uint16_t ExternalUnsignedShortArray::get(int index) {
1950 ASSERT((index >= 0) && (index < this->length()));
1951 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
1952 return ptr[index];
1953}
1954
1955
1956void ExternalUnsignedShortArray::set(int index, uint16_t value) {
1957 ASSERT((index >= 0) && (index < this->length()));
1958 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
1959 ptr[index] = value;
1960}
1961
1962
1963int32_t ExternalIntArray::get(int index) {
1964 ASSERT((index >= 0) && (index < this->length()));
1965 int32_t* ptr = static_cast<int32_t*>(external_pointer());
1966 return ptr[index];
1967}
1968
1969
1970void ExternalIntArray::set(int index, int32_t value) {
1971 ASSERT((index >= 0) && (index < this->length()));
1972 int32_t* ptr = static_cast<int32_t*>(external_pointer());
1973 ptr[index] = value;
1974}
1975
1976
1977uint32_t ExternalUnsignedIntArray::get(int index) {
1978 ASSERT((index >= 0) && (index < this->length()));
1979 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
1980 return ptr[index];
1981}
1982
1983
1984void ExternalUnsignedIntArray::set(int index, uint32_t value) {
1985 ASSERT((index >= 0) && (index < this->length()));
1986 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
1987 ptr[index] = value;
1988}
1989
1990
1991float ExternalFloatArray::get(int index) {
1992 ASSERT((index >= 0) && (index < this->length()));
1993 float* ptr = static_cast<float*>(external_pointer());
1994 return ptr[index];
1995}
1996
1997
1998void ExternalFloatArray::set(int index, float value) {
1999 ASSERT((index >= 0) && (index < this->length()));
2000 float* ptr = static_cast<float*>(external_pointer());
2001 ptr[index] = value;
2002}
2003
2004
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002005int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002006 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2007}
2008
2009
2010int Map::inobject_properties() {
2011 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002012}
2013
2014
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002015int Map::pre_allocated_property_fields() {
2016 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2017}
2018
2019
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002020int HeapObject::SizeFromMap(Map* map) {
2021 InstanceType instance_type = map->instance_type();
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002022 // Only inline the most frequent cases.
2023 if (instance_type == JS_OBJECT_TYPE ||
2024 (instance_type & (kIsNotStringMask | kStringRepresentationMask)) ==
2025 (kStringTag | kConsStringTag) ||
2026 instance_type == JS_ARRAY_TYPE) return map->instance_size();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002027 if (instance_type == FIXED_ARRAY_TYPE) {
2028 return reinterpret_cast<FixedArray*>(this)->FixedArraySize();
2029 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002030 if (instance_type == BYTE_ARRAY_TYPE) {
2031 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2032 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002033 // Otherwise do the general size computation.
2034 return SlowSizeFromMap(map);
2035}
2036
2037
2038void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002039 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002040 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002041 ASSERT(0 <= value && value < 256);
2042 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2043}
2044
2045
ager@chromium.org7c537e22008-10-16 08:43:32 +00002046void Map::set_inobject_properties(int value) {
2047 ASSERT(0 <= value && value < 256);
2048 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2049}
2050
2051
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002052void Map::set_pre_allocated_property_fields(int value) {
2053 ASSERT(0 <= value && value < 256);
2054 WRITE_BYTE_FIELD(this,
2055 kPreAllocatedPropertyFieldsOffset,
2056 static_cast<byte>(value));
2057}
2058
2059
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002060InstanceType Map::instance_type() {
2061 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2062}
2063
2064
2065void Map::set_instance_type(InstanceType value) {
2066 ASSERT(0 <= value && value < 256);
2067 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2068}
2069
2070
2071int Map::unused_property_fields() {
2072 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2073}
2074
2075
2076void Map::set_unused_property_fields(int value) {
2077 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2078}
2079
2080
2081byte Map::bit_field() {
2082 return READ_BYTE_FIELD(this, kBitFieldOffset);
2083}
2084
2085
2086void Map::set_bit_field(byte value) {
2087 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2088}
2089
2090
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002091byte Map::bit_field2() {
2092 return READ_BYTE_FIELD(this, kBitField2Offset);
2093}
2094
2095
2096void Map::set_bit_field2(byte value) {
2097 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2098}
2099
2100
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002101void Map::set_non_instance_prototype(bool value) {
2102 if (value) {
2103 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2104 } else {
2105 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2106 }
2107}
2108
2109
2110bool Map::has_non_instance_prototype() {
2111 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2112}
2113
2114
ager@chromium.org870a0b62008-11-04 11:43:05 +00002115void Map::set_is_access_check_needed(bool access_check_needed) {
2116 if (access_check_needed) {
2117 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2118 } else {
2119 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2120 }
2121}
2122
2123
2124bool Map::is_access_check_needed() {
2125 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2126}
2127
2128
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002129Code::Flags Code::flags() {
2130 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2131}
2132
2133
2134void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002135 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002136 // Make sure that all call stubs have an arguments count.
2137 ASSERT(ExtractKindFromFlags(flags) != CALL_IC ||
2138 ExtractArgumentsCountFromFlags(flags) >= 0);
2139 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2140}
2141
2142
2143Code::Kind Code::kind() {
2144 return ExtractKindFromFlags(flags());
2145}
2146
2147
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002148InLoopFlag Code::ic_in_loop() {
2149 return ExtractICInLoopFromFlags(flags());
2150}
2151
2152
kasper.lund7276f142008-07-30 08:49:36 +00002153InlineCacheState Code::ic_state() {
2154 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002155 // Only allow uninitialized or debugger states for non-IC code
2156 // objects. This is used in the debugger to determine whether or not
2157 // a call to code object has been replaced with a debug break call.
2158 ASSERT(is_inline_cache_stub() ||
2159 result == UNINITIALIZED ||
2160 result == DEBUG_BREAK ||
2161 result == DEBUG_PREPARE_STEP_IN);
2162 return result;
2163}
2164
2165
2166PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002167 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002168 return ExtractTypeFromFlags(flags());
2169}
2170
2171
2172int Code::arguments_count() {
2173 ASSERT(is_call_stub() || kind() == STUB);
2174 return ExtractArgumentsCountFromFlags(flags());
2175}
2176
2177
2178CodeStub::Major Code::major_key() {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002179 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002180 return static_cast<CodeStub::Major>(READ_BYTE_FIELD(this,
2181 kStubMajorKeyOffset));
2182}
2183
2184
2185void Code::set_major_key(CodeStub::Major major) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002186 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002187 ASSERT(0 <= major && major < 256);
2188 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002189}
2190
2191
2192bool Code::is_inline_cache_stub() {
2193 Kind kind = this->kind();
2194 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2195}
2196
2197
2198Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002199 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002200 InlineCacheState ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002201 PropertyType type,
2202 int argc) {
2203 // Compute the bit mask.
2204 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002205 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002206 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002207 bits |= type << kFlagsTypeShift;
2208 bits |= argc << kFlagsArgumentsCountShift;
2209 // Cast to flags and validate result before returning it.
2210 Flags result = static_cast<Flags>(bits);
2211 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002212 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002213 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002214 ASSERT(ExtractTypeFromFlags(result) == type);
2215 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2216 return result;
2217}
2218
2219
2220Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2221 PropertyType type,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002222 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002223 int argc) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002224 return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002225}
2226
2227
2228Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2229 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2230 return static_cast<Kind>(bits);
2231}
2232
2233
kasper.lund7276f142008-07-30 08:49:36 +00002234InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2235 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002236 return static_cast<InlineCacheState>(bits);
2237}
2238
2239
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002240InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2241 int bits = (flags & kFlagsICInLoopMask);
2242 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2243}
2244
2245
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002246PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2247 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2248 return static_cast<PropertyType>(bits);
2249}
2250
2251
2252int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2253 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2254}
2255
2256
2257Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2258 int bits = flags & ~kFlagsTypeMask;
2259 return static_cast<Flags>(bits);
2260}
2261
2262
ager@chromium.org8bb60582008-12-11 12:02:20 +00002263Code* Code::GetCodeFromTargetAddress(Address address) {
2264 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2265 // GetCodeFromTargetAddress might be called when marking objects during mark
2266 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2267 // Code::cast. Code::cast does not work when the object's map is
2268 // marked.
2269 Code* result = reinterpret_cast<Code*>(code);
2270 return result;
2271}
2272
2273
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002274Object* Map::prototype() {
2275 return READ_FIELD(this, kPrototypeOffset);
2276}
2277
2278
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002279void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002280 ASSERT(value->IsNull() || value->IsJSObject());
2281 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002282 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002283}
2284
2285
2286ACCESSORS(Map, instance_descriptors, DescriptorArray,
2287 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002288ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002289ACCESSORS(Map, constructor, Object, kConstructorOffset)
2290
2291ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2292ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
2293
2294ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2295ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002296ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002297
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002298ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002299
2300ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2301ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2302ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2303ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2304ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002305ACCESSORS(AccessorInfo, load_stub_cache, Object, kLoadStubCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002306
2307ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2308ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2309ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2310
2311ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2312ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2313ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2314ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2315ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2316ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2317
2318ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2319ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2320
2321ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2322ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2323
2324ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2325ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002326ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2327 kPropertyAccessorsOffset)
2328ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2329 kPrototypeTemplateOffset)
2330ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2331ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2332 kNamedPropertyHandlerOffset)
2333ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2334 kIndexedPropertyHandlerOffset)
2335ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2336 kInstanceTemplateOffset)
2337ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2338ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002339ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2340 kInstanceCallHandlerOffset)
2341ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2342 kAccessCheckInfoOffset)
2343ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2344
2345ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002346ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2347 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002348
2349ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2350ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2351
2352ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2353
2354ACCESSORS(Script, source, Object, kSourceOffset)
2355ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002356ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002357ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2358ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002359ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002360ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002361ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2362ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002363ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00002364ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002365ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002366ACCESSORS(Script, eval_from_instructions_offset, Smi,
2367 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002368
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002369#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002370ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2371ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2372ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2373ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2374
2375ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2376ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2377ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2378ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002379#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002380
2381ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002382ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002383ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2384 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002385ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002386ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2387ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002388ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002389ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2390 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002391
2392BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2393 kHiddenPrototypeBit)
2394BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2395BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2396 kNeedsAccessCheckBit)
2397BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2398 kIsExpressionBit)
2399BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2400 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002401BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002402 has_only_simple_this_property_assignments,
2403 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002404BOOL_ACCESSORS(SharedFunctionInfo,
2405 compiler_hints,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002406 try_full_codegen,
2407 kTryFullCodegen)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002408
2409INT_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2410INT_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
2411 kFormalParameterCountOffset)
2412INT_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
2413 kExpectedNofPropertiesOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002414INT_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002415INT_ACCESSORS(SharedFunctionInfo, start_position_and_type,
2416 kStartPositionAndTypeOffset)
2417INT_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2418INT_ACCESSORS(SharedFunctionInfo, function_token_position,
2419 kFunctionTokenPositionOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002420INT_ACCESSORS(SharedFunctionInfo, compiler_hints,
2421 kCompilerHintsOffset)
2422INT_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
2423 kThisPropertyAssignmentsCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002424
2425
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002426ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
2427ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
2428
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00002429bool Script::HasValidSource() {
2430 Object* src = this->source();
2431 if (!src->IsString()) return true;
2432 String* src_str = String::cast(src);
2433 if (!StringShape(src_str).IsExternal()) return true;
2434 if (src_str->IsAsciiRepresentation()) {
2435 return ExternalAsciiString::cast(src)->resource() != NULL;
2436 } else if (src_str->IsTwoByteRepresentation()) {
2437 return ExternalTwoByteString::cast(src)->resource() != NULL;
2438 }
2439 return true;
2440}
2441
2442
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002443void SharedFunctionInfo::DontAdaptArguments() {
2444 ASSERT(code()->kind() == Code::BUILTIN);
2445 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2446}
2447
2448
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002449int SharedFunctionInfo::start_position() {
2450 return start_position_and_type() >> kStartPositionShift;
2451}
2452
2453
2454void SharedFunctionInfo::set_start_position(int start_position) {
2455 set_start_position_and_type((start_position << kStartPositionShift)
2456 | (start_position_and_type() & ~kStartPositionMask));
2457}
2458
2459
2460Code* SharedFunctionInfo::code() {
2461 return Code::cast(READ_FIELD(this, kCodeOffset));
2462}
2463
2464
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002465void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002466 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002467 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002468}
2469
2470
2471bool SharedFunctionInfo::is_compiled() {
2472 // TODO(1242782): Create a code kind for uncompiled code.
2473 return code()->kind() != Code::STUB;
2474}
2475
2476
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002477bool SharedFunctionInfo::IsApiFunction() {
2478 return function_data()->IsFunctionTemplateInfo();
2479}
2480
2481
2482FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
2483 ASSERT(IsApiFunction());
2484 return FunctionTemplateInfo::cast(function_data());
2485}
2486
2487
2488bool SharedFunctionInfo::HasCustomCallGenerator() {
2489 return function_data()->IsProxy();
2490}
2491
2492
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002493bool JSFunction::IsBoilerplate() {
2494 return map() == Heap::boilerplate_function_map();
2495}
2496
2497
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002498bool JSFunction::IsBuiltin() {
2499 return context()->global()->IsJSBuiltinsObject();
2500}
2501
2502
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002503Code* JSFunction::code() {
2504 return shared()->code();
2505}
2506
2507
2508void JSFunction::set_code(Code* value) {
2509 shared()->set_code(value);
2510}
2511
2512
2513Context* JSFunction::context() {
2514 return Context::cast(READ_FIELD(this, kContextOffset));
2515}
2516
2517
2518Object* JSFunction::unchecked_context() {
2519 return READ_FIELD(this, kContextOffset);
2520}
2521
2522
2523void JSFunction::set_context(Object* value) {
2524 ASSERT(value == Heap::undefined_value() || value->IsContext());
2525 WRITE_FIELD(this, kContextOffset, value);
2526 WRITE_BARRIER(this, kContextOffset);
2527}
2528
2529ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2530 kPrototypeOrInitialMapOffset)
2531
2532
2533Map* JSFunction::initial_map() {
2534 return Map::cast(prototype_or_initial_map());
2535}
2536
2537
2538void JSFunction::set_initial_map(Map* value) {
2539 set_prototype_or_initial_map(value);
2540}
2541
2542
2543bool JSFunction::has_initial_map() {
2544 return prototype_or_initial_map()->IsMap();
2545}
2546
2547
2548bool JSFunction::has_instance_prototype() {
2549 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2550}
2551
2552
2553bool JSFunction::has_prototype() {
2554 return map()->has_non_instance_prototype() || has_instance_prototype();
2555}
2556
2557
2558Object* JSFunction::instance_prototype() {
2559 ASSERT(has_instance_prototype());
2560 if (has_initial_map()) return initial_map()->prototype();
2561 // When there is no initial map and the prototype is a JSObject, the
2562 // initial map field is used for the prototype field.
2563 return prototype_or_initial_map();
2564}
2565
2566
2567Object* JSFunction::prototype() {
2568 ASSERT(has_prototype());
2569 // If the function's prototype property has been set to a non-JSObject
2570 // value, that value is stored in the constructor field of the map.
2571 if (map()->has_non_instance_prototype()) return map()->constructor();
2572 return instance_prototype();
2573}
2574
2575
2576bool JSFunction::is_compiled() {
2577 return shared()->is_compiled();
2578}
2579
2580
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002581int JSFunction::NumberOfLiterals() {
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002582 ASSERT(!IsBoilerplate());
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002583 return literals()->length();
2584}
2585
2586
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002587Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2588 ASSERT(0 <= id && id < kJSBuiltinsCount);
2589 return READ_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize));
2590}
2591
2592
2593void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2594 Object* value) {
2595 ASSERT(0 <= id && id < kJSBuiltinsCount);
2596 WRITE_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize), value);
2597 WRITE_BARRIER(this, kJSBuiltinsOffset + (id * kPointerSize));
2598}
2599
2600
2601Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00002602 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002603}
2604
2605
2606void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002607 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002608}
2609
2610
2611void Proxy::ProxyIterateBody(ObjectVisitor* visitor) {
2612 visitor->VisitExternalReference(
2613 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
2614}
2615
2616
2617ACCESSORS(JSValue, value, Object, kValueOffset)
2618
2619
2620JSValue* JSValue::cast(Object* obj) {
2621 ASSERT(obj->IsJSValue());
2622 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2623 return reinterpret_cast<JSValue*>(obj);
2624}
2625
2626
2627INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
2628INT_ACCESSORS(Code, relocation_size, kRelocationSizeOffset)
2629INT_ACCESSORS(Code, sinfo_size, kSInfoSizeOffset)
2630
2631
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002632byte* Code::instruction_start() {
2633 return FIELD_ADDR(this, kHeaderSize);
2634}
2635
2636
2637int Code::body_size() {
2638 return RoundUp(instruction_size() + relocation_size(), kObjectAlignment);
2639}
2640
2641
2642byte* Code::relocation_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002643 return FIELD_ADDR(this, kHeaderSize + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002644}
2645
2646
2647byte* Code::entry() {
2648 return instruction_start();
2649}
2650
2651
2652bool Code::contains(byte* pc) {
2653 return (instruction_start() <= pc) &&
2654 (pc < instruction_start() + instruction_size());
2655}
2656
2657
2658byte* Code::sinfo_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002659 return FIELD_ADDR(this, kHeaderSize + body_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002660}
2661
2662
2663ACCESSORS(JSArray, length, Object, kLengthOffset)
2664
2665
ager@chromium.org236ad962008-09-25 09:45:57 +00002666ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00002667
2668
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002669JSRegExp::Type JSRegExp::TypeTag() {
2670 Object* data = this->data();
2671 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
2672 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
2673 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00002674}
2675
2676
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002677int JSRegExp::CaptureCount() {
2678 switch (TypeTag()) {
2679 case ATOM:
2680 return 0;
2681 case IRREGEXP:
2682 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
2683 default:
2684 UNREACHABLE();
2685 return -1;
2686 }
2687}
2688
2689
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002690JSRegExp::Flags JSRegExp::GetFlags() {
2691 ASSERT(this->data()->IsFixedArray());
2692 Object* data = this->data();
2693 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
2694 return Flags(smi->value());
2695}
2696
2697
2698String* JSRegExp::Pattern() {
2699 ASSERT(this->data()->IsFixedArray());
2700 Object* data = this->data();
2701 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
2702 return pattern;
2703}
2704
2705
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002706Object* JSRegExp::DataAt(int index) {
2707 ASSERT(TypeTag() != NOT_COMPILED);
2708 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00002709}
2710
2711
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002712void JSRegExp::SetDataAt(int index, Object* value) {
2713 ASSERT(TypeTag() != NOT_COMPILED);
2714 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
2715 FixedArray::cast(data())->set(index, value);
2716}
2717
2718
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002719JSObject::ElementsKind JSObject::GetElementsKind() {
2720 Array* array = elements();
2721 if (array->IsFixedArray()) {
2722 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a FixedArray.
2723 if (array->map() == Heap::fixed_array_map()) {
2724 return FAST_ELEMENTS;
2725 }
2726 ASSERT(array->IsDictionary());
2727 return DICTIONARY_ELEMENTS;
2728 }
ager@chromium.org3811b432009-10-28 14:53:37 +00002729 if (array->IsExternalArray()) {
2730 switch (array->map()->instance_type()) {
2731 case EXTERNAL_BYTE_ARRAY_TYPE:
2732 return EXTERNAL_BYTE_ELEMENTS;
2733 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
2734 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2735 case EXTERNAL_SHORT_ARRAY_TYPE:
2736 return EXTERNAL_SHORT_ELEMENTS;
2737 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
2738 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2739 case EXTERNAL_INT_ARRAY_TYPE:
2740 return EXTERNAL_INT_ELEMENTS;
2741 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
2742 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
2743 default:
2744 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
2745 return EXTERNAL_FLOAT_ELEMENTS;
2746 }
2747 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002748 ASSERT(array->IsPixelArray());
2749 return PIXEL_ELEMENTS;
2750}
2751
2752
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002753bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002754 return GetElementsKind() == FAST_ELEMENTS;
2755}
2756
2757
2758bool JSObject::HasDictionaryElements() {
2759 return GetElementsKind() == DICTIONARY_ELEMENTS;
2760}
2761
2762
2763bool JSObject::HasPixelElements() {
2764 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002765}
2766
2767
ager@chromium.org3811b432009-10-28 14:53:37 +00002768bool JSObject::HasExternalArrayElements() {
2769 return (HasExternalByteElements() ||
2770 HasExternalUnsignedByteElements() ||
2771 HasExternalShortElements() ||
2772 HasExternalUnsignedShortElements() ||
2773 HasExternalIntElements() ||
2774 HasExternalUnsignedIntElements() ||
2775 HasExternalFloatElements());
2776}
2777
2778
2779bool JSObject::HasExternalByteElements() {
2780 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
2781}
2782
2783
2784bool JSObject::HasExternalUnsignedByteElements() {
2785 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2786}
2787
2788
2789bool JSObject::HasExternalShortElements() {
2790 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
2791}
2792
2793
2794bool JSObject::HasExternalUnsignedShortElements() {
2795 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2796}
2797
2798
2799bool JSObject::HasExternalIntElements() {
2800 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
2801}
2802
2803
2804bool JSObject::HasExternalUnsignedIntElements() {
2805 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
2806}
2807
2808
2809bool JSObject::HasExternalFloatElements() {
2810 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
2811}
2812
2813
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002814bool JSObject::HasNamedInterceptor() {
2815 return map()->has_named_interceptor();
2816}
2817
2818
2819bool JSObject::HasIndexedInterceptor() {
2820 return map()->has_indexed_interceptor();
2821}
2822
2823
ager@chromium.org5c838252010-02-19 08:53:10 +00002824bool JSObject::AllowsSetElementsLength() {
2825 bool result = elements()->IsFixedArray();
2826 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
2827 return result;
2828}
2829
2830
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002831StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002832 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002833 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002834}
2835
2836
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002837NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002838 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002839 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002840}
2841
2842
2843bool String::HasHashCode() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002844 return (hash_field() & kHashComputedMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002845}
2846
2847
2848uint32_t String::Hash() {
2849 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002850 uint32_t field = hash_field();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002851 if (field & kHashComputedMask) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002852 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002853 return ComputeAndSetHash();
2854}
2855
2856
ager@chromium.org7c537e22008-10-16 08:43:32 +00002857StringHasher::StringHasher(int length)
2858 : length_(length),
2859 raw_running_hash_(0),
2860 array_index_(0),
2861 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
2862 is_first_char_(true),
2863 is_valid_(true) { }
2864
2865
2866bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002867 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00002868}
2869
2870
2871void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002872 // Use the Jenkins one-at-a-time hash function to update the hash
2873 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002874 raw_running_hash_ += c;
2875 raw_running_hash_ += (raw_running_hash_ << 10);
2876 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002877 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002878 if (is_array_index_) {
2879 if (c < '0' || c > '9') {
2880 is_array_index_ = false;
2881 } else {
2882 int d = c - '0';
2883 if (is_first_char_) {
2884 is_first_char_ = false;
2885 if (c == '0' && length_ > 1) {
2886 is_array_index_ = false;
2887 return;
2888 }
2889 }
2890 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
2891 is_array_index_ = false;
2892 } else {
2893 array_index_ = array_index_ * 10 + d;
2894 }
2895 }
2896 }
2897}
2898
2899
2900void StringHasher::AddCharacterNoIndex(uc32 c) {
2901 ASSERT(!is_array_index());
2902 raw_running_hash_ += c;
2903 raw_running_hash_ += (raw_running_hash_ << 10);
2904 raw_running_hash_ ^= (raw_running_hash_ >> 6);
2905}
2906
2907
2908uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002909 // Get the calculated raw hash value and do some more bit ops to distribute
2910 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002911 uint32_t result = raw_running_hash_;
2912 result += (result << 3);
2913 result ^= (result >> 11);
2914 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002915 if (result == 0) {
2916 result = 27;
2917 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002918 return result;
2919}
2920
2921
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002922bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002923 uint32_t field = hash_field();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002924 if ((field & kHashComputedMask) && !(field & kIsArrayIndexMask)) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002925 return SlowAsArrayIndex(index);
2926}
2927
2928
2929Object* JSObject::GetPrototype() {
2930 return JSObject::cast(this)->map()->prototype();
2931}
2932
2933
2934PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
2935 return GetPropertyAttributeWithReceiver(this, key);
2936}
2937
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002938// TODO(504): this may be useful in other places too where JSGlobalProxy
2939// is used.
2940Object* JSObject::BypassGlobalProxy() {
2941 if (IsJSGlobalProxy()) {
2942 Object* proto = GetPrototype();
2943 if (proto->IsNull()) return Heap::undefined_value();
2944 ASSERT(proto->IsJSGlobalObject());
2945 return proto;
2946 }
2947 return this;
2948}
2949
2950
2951bool JSObject::HasHiddenPropertiesObject() {
2952 ASSERT(!IsJSGlobalProxy());
2953 return GetPropertyAttributePostInterceptor(this,
2954 Heap::hidden_symbol(),
2955 false) != ABSENT;
2956}
2957
2958
2959Object* JSObject::GetHiddenPropertiesObject() {
2960 ASSERT(!IsJSGlobalProxy());
2961 PropertyAttributes attributes;
2962 return GetLocalPropertyPostInterceptor(this,
2963 Heap::hidden_symbol(),
2964 &attributes);
2965}
2966
2967
2968Object* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
2969 ASSERT(!IsJSGlobalProxy());
2970 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
2971 hidden_obj,
2972 DONT_ENUM);
2973}
2974
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002975
2976bool JSObject::HasElement(uint32_t index) {
2977 return HasElementWithReceiver(this, index);
2978}
2979
2980
2981bool AccessorInfo::all_can_read() {
2982 return BooleanBit::get(flag(), kAllCanReadBit);
2983}
2984
2985
2986void AccessorInfo::set_all_can_read(bool value) {
2987 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
2988}
2989
2990
2991bool AccessorInfo::all_can_write() {
2992 return BooleanBit::get(flag(), kAllCanWriteBit);
2993}
2994
2995
2996void AccessorInfo::set_all_can_write(bool value) {
2997 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
2998}
2999
3000
ager@chromium.org870a0b62008-11-04 11:43:05 +00003001bool AccessorInfo::prohibits_overwriting() {
3002 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3003}
3004
3005
3006void AccessorInfo::set_prohibits_overwriting(bool value) {
3007 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3008}
3009
3010
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003011PropertyAttributes AccessorInfo::property_attributes() {
3012 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3013}
3014
3015
3016void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3017 ASSERT(AttributesField::is_valid(attributes));
3018 int rest_value = flag()->value() & ~AttributesField::mask();
3019 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3020}
3021
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003022template<typename Shape, typename Key>
3023void Dictionary<Shape, Key>::SetEntry(int entry,
3024 Object* key,
3025 Object* value,
3026 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003027 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003028 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003029 AssertNoAllocation no_gc;
3030 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003031 FixedArray::set(index, key, mode);
3032 FixedArray::set(index+1, value, mode);
3033 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003034}
3035
3036
3037void Map::ClearCodeCache() {
3038 // No write barrier is needed since empty_fixed_array is not in new space.
3039 // Please note this function is used during marking:
3040 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003041 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3042 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003043}
3044
3045
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003046void JSArray::EnsureSize(int required_size) {
3047 ASSERT(HasFastElements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003048 Array* elts = elements();
3049 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3050 if (elts->length() < required_size) {
3051 // Doubling in size would be overkill, but leave some slack to avoid
3052 // constantly growing.
3053 Expand(required_size + (required_size >> 3));
3054 // It's a performance benefit to keep a frequently used array in new-space.
3055 } else if (!Heap::new_space()->Contains(elts) &&
3056 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3057 // Expand will allocate a new backing store in new space even if the size
3058 // we asked for isn't larger than what we had before.
3059 Expand(required_size);
3060 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003061}
3062
3063
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003064void JSArray::set_length(Smi* length) {
3065 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3066}
3067
3068
ager@chromium.org7c537e22008-10-16 08:43:32 +00003069void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003070 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003071 set_elements(storage);
3072}
3073
3074
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003075Object* FixedArray::Copy() {
3076 if (length() == 0) return this;
3077 return Heap::CopyFixedArray(this);
3078}
3079
3080
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003081#undef CAST_ACCESSOR
3082#undef INT_ACCESSORS
3083#undef SMI_ACCESSORS
3084#undef ACCESSORS
3085#undef FIELD_ADDR
3086#undef READ_FIELD
3087#undef WRITE_FIELD
3088#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003089#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003090#undef READ_MEMADDR_FIELD
3091#undef WRITE_MEMADDR_FIELD
3092#undef READ_DOUBLE_FIELD
3093#undef WRITE_DOUBLE_FIELD
3094#undef READ_INT_FIELD
3095#undef WRITE_INT_FIELD
3096#undef READ_SHORT_FIELD
3097#undef WRITE_SHORT_FIELD
3098#undef READ_BYTE_FIELD
3099#undef WRITE_BYTE_FIELD
3100
3101
3102} } // namespace v8::internal
3103
3104#endif // V8_OBJECTS_INL_H_