blob: 621a3f84a31b6727f4bf05115d77d6db9053b8ab [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) || \
kmillikin@chromium.orgb8dc8eb2010-04-01 07:13:38 +0000745 !Heap::InNewSpace(READ_FIELD(object, offset)) || \
746 Page::IsRSetSet(object->address(), offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000747 }
748
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000749#define READ_DOUBLE_FIELD(p, offset) \
750 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
751
752#define WRITE_DOUBLE_FIELD(p, offset, value) \
753 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
754
755#define READ_INT_FIELD(p, offset) \
756 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
757
758#define WRITE_INT_FIELD(p, offset, value) \
759 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
760
ager@chromium.org3e875802009-06-29 08:26:34 +0000761#define READ_INTPTR_FIELD(p, offset) \
762 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
763
764#define WRITE_INTPTR_FIELD(p, offset, value) \
765 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
766
ager@chromium.org7c537e22008-10-16 08:43:32 +0000767#define READ_UINT32_FIELD(p, offset) \
768 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
769
770#define WRITE_UINT32_FIELD(p, offset, value) \
771 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
772
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000773#define READ_SHORT_FIELD(p, offset) \
774 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
775
776#define WRITE_SHORT_FIELD(p, offset, value) \
777 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
778
779#define READ_BYTE_FIELD(p, offset) \
780 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
781
782#define WRITE_BYTE_FIELD(p, offset, value) \
783 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
784
785
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000786Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
787 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000788}
789
790
791int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000792 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000793}
794
795
796Smi* Smi::FromInt(int value) {
797 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000798 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000799 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000800 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000801 return reinterpret_cast<Smi*>(tagged_value);
802}
803
804
805Smi* Smi::FromIntptr(intptr_t value) {
806 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000807 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
808 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000809}
810
811
812Failure::Type Failure::type() const {
813 return static_cast<Type>(value() & kFailureTypeTagMask);
814}
815
816
817bool Failure::IsInternalError() const {
818 return type() == INTERNAL_ERROR;
819}
820
821
822bool Failure::IsOutOfMemoryException() const {
823 return type() == OUT_OF_MEMORY_EXCEPTION;
824}
825
826
827int Failure::requested() const {
828 const int kShiftBits =
829 kFailureTypeTagSize + kSpaceTagSize - kObjectAlignmentBits;
830 STATIC_ASSERT(kShiftBits >= 0);
831 ASSERT(type() == RETRY_AFTER_GC);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000832 return static_cast<int>(value() >> kShiftBits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000833}
834
835
836AllocationSpace Failure::allocation_space() const {
837 ASSERT_EQ(RETRY_AFTER_GC, type());
838 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
839 & kSpaceTagMask);
840}
841
842
843Failure* Failure::InternalError() {
844 return Construct(INTERNAL_ERROR);
845}
846
847
848Failure* Failure::Exception() {
849 return Construct(EXCEPTION);
850}
851
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000852
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000853Failure* Failure::OutOfMemoryException() {
854 return Construct(OUT_OF_MEMORY_EXCEPTION);
855}
856
857
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000858intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000859 return static_cast<intptr_t>(
860 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000861}
862
863
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000864Failure* Failure::RetryAfterGC(int requested_bytes) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +0000865 // Assert that the space encoding fits in the three bytes allotted for it.
866 ASSERT((LAST_SPACE & ~kSpaceTagMask) == 0);
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000867 uintptr_t requested =
868 static_cast<uintptr_t>(requested_bytes >> kObjectAlignmentBits);
869 int tag_bits = kSpaceTagSize + kFailureTypeTagSize + kFailureTagSize;
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000870 if (((requested << tag_bits) >> tag_bits) != requested) {
871 // No room for entire requested size in the bits. Round down to
872 // maximally representable size.
873 requested = static_cast<intptr_t>(
874 (~static_cast<uintptr_t>(0)) >> (tag_bits + 1));
875 }
ager@chromium.orgc4c92722009-11-18 14:12:51 +0000876 int value = static_cast<int>(requested << kSpaceTagSize) | NEW_SPACE;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000877 return Construct(RETRY_AFTER_GC, value);
878}
879
880
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000881Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000882 uintptr_t info =
883 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000884 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000885 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000886}
887
888
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000889bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000890#ifdef DEBUG
891 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
892#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000893
894#ifdef V8_TARGET_ARCH_X64
895 // To be representable as a long smi, the value must be a 32-bit integer.
896 bool result = (value == static_cast<int32_t>(value));
897#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000898 // To be representable as an tagged small integer, the two
899 // most-significant bits of 'value' must be either 00 or 11 due to
900 // sign-extension. To check this we add 01 to the two
901 // most-significant bits, and check if the most-significant bit is 0
902 //
903 // CAUTION: The original code below:
904 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
905 // may lead to incorrect results according to the C language spec, and
906 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
907 // compiler may produce undefined results in case of signed integer
908 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000909 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +0000910#endif
ager@chromium.org9085a012009-05-11 19:22:57 +0000911 ASSERT(result == in_range);
912 return result;
913}
914
915
kasper.lund7276f142008-07-30 08:49:36 +0000916MapWord MapWord::FromMap(Map* map) {
917 return MapWord(reinterpret_cast<uintptr_t>(map));
918}
919
920
921Map* MapWord::ToMap() {
922 return reinterpret_cast<Map*>(value_);
923}
924
925
926bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000927 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000928}
929
930
931MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000932 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
933 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000934}
935
936
937HeapObject* MapWord::ToForwardingAddress() {
938 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000939 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000940}
941
942
943bool MapWord::IsMarked() {
944 return (value_ & kMarkingMask) == 0;
945}
946
947
948void MapWord::SetMark() {
949 value_ &= ~kMarkingMask;
950}
951
952
953void MapWord::ClearMark() {
954 value_ |= kMarkingMask;
955}
956
957
958bool MapWord::IsOverflowed() {
959 return (value_ & kOverflowMask) != 0;
960}
961
962
963void MapWord::SetOverflow() {
964 value_ |= kOverflowMask;
965}
966
967
968void MapWord::ClearOverflow() {
969 value_ &= ~kOverflowMask;
970}
971
972
973MapWord MapWord::EncodeAddress(Address map_address, int offset) {
974 // Offset is the distance in live bytes from the first live object in the
975 // same page. The offset between two objects in the same page should not
976 // exceed the object area size of a page.
977 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
978
sgjesse@chromium.org846fb742009-12-18 08:56:33 +0000979 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +0000980 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
981
982 Page* map_page = Page::FromAddress(map_address);
983 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
984
sgjesse@chromium.org846fb742009-12-18 08:56:33 +0000985 uintptr_t map_page_offset =
986 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +0000987
988 uintptr_t encoding =
989 (compact_offset << kForwardingOffsetShift) |
990 (map_page_offset << kMapPageOffsetShift) |
991 (map_page->mc_page_index << kMapPageIndexShift);
992 return MapWord(encoding);
993}
994
995
996Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000997 int map_page_index =
998 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +0000999 ASSERT_MAP_PAGE_INDEX(map_page_index);
1000
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001001 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001002 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1003 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001004
1005 return (map_space->PageAddress(map_page_index) + map_page_offset);
1006}
1007
1008
1009int MapWord::DecodeOffset() {
1010 // The offset field is represented in the kForwardingOffsetBits
1011 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001012 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1013 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1014 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001015}
1016
1017
1018MapWord MapWord::FromEncodedAddress(Address address) {
1019 return MapWord(reinterpret_cast<uintptr_t>(address));
1020}
1021
1022
1023Address MapWord::ToEncodedAddress() {
1024 return reinterpret_cast<Address>(value_);
1025}
1026
1027
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001028#ifdef DEBUG
1029void HeapObject::VerifyObjectField(int offset) {
1030 VerifyPointer(READ_FIELD(this, offset));
1031}
1032#endif
1033
1034
1035Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001036 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001037}
1038
1039
1040void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001041 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001042}
1043
1044
kasper.lund7276f142008-07-30 08:49:36 +00001045MapWord HeapObject::map_word() {
1046 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1047}
1048
1049
1050void HeapObject::set_map_word(MapWord map_word) {
1051 // WRITE_FIELD does not update the remembered set, but there is no need
1052 // here.
1053 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1054}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001055
1056
1057HeapObject* HeapObject::FromAddress(Address address) {
1058 ASSERT_TAG_ALIGNED(address);
1059 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1060}
1061
1062
1063Address HeapObject::address() {
1064 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1065}
1066
1067
1068int HeapObject::Size() {
1069 return SizeFromMap(map());
1070}
1071
1072
1073void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1074 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1075 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1076}
1077
1078
1079void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1080 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1081}
1082
1083
kasper.lund7276f142008-07-30 08:49:36 +00001084bool HeapObject::IsMarked() {
1085 return map_word().IsMarked();
1086}
1087
1088
1089void HeapObject::SetMark() {
1090 ASSERT(!IsMarked());
1091 MapWord first_word = map_word();
1092 first_word.SetMark();
1093 set_map_word(first_word);
1094}
1095
1096
1097void HeapObject::ClearMark() {
1098 ASSERT(IsMarked());
1099 MapWord first_word = map_word();
1100 first_word.ClearMark();
1101 set_map_word(first_word);
1102}
1103
1104
1105bool HeapObject::IsOverflowed() {
1106 return map_word().IsOverflowed();
1107}
1108
1109
1110void HeapObject::SetOverflow() {
1111 MapWord first_word = map_word();
1112 first_word.SetOverflow();
1113 set_map_word(first_word);
1114}
1115
1116
1117void HeapObject::ClearOverflow() {
1118 ASSERT(IsOverflowed());
1119 MapWord first_word = map_word();
1120 first_word.ClearOverflow();
1121 set_map_word(first_word);
1122}
1123
1124
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001125double HeapNumber::value() {
1126 return READ_DOUBLE_FIELD(this, kValueOffset);
1127}
1128
1129
1130void HeapNumber::set_value(double value) {
1131 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1132}
1133
1134
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001135int HeapNumber::get_exponent() {
1136 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1137 kExponentShift) - kExponentBias;
1138}
1139
1140
1141int HeapNumber::get_sign() {
1142 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1143}
1144
1145
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001146ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001147
1148
1149Array* JSObject::elements() {
1150 Object* array = READ_FIELD(this, kElementsOffset);
1151 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001152 ASSERT(array->IsFixedArray() || array->IsPixelArray() ||
1153 array->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001154 return reinterpret_cast<Array*>(array);
1155}
1156
1157
1158void JSObject::set_elements(Array* value, WriteBarrierMode mode) {
1159 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001160 ASSERT(value->IsFixedArray() || value->IsPixelArray() ||
1161 value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001162 WRITE_FIELD(this, kElementsOffset, value);
1163 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode);
1164}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001165
1166
1167void JSObject::initialize_properties() {
1168 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1169 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1170}
1171
1172
1173void JSObject::initialize_elements() {
1174 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1175 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1176}
1177
1178
1179ACCESSORS(Oddball, to_string, String, kToStringOffset)
1180ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1181
1182
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001183Object* JSGlobalPropertyCell::value() {
1184 return READ_FIELD(this, kValueOffset);
1185}
1186
1187
1188void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1189 // The write barrier is not used for global property cells.
1190 ASSERT(!val->IsJSGlobalPropertyCell());
1191 WRITE_FIELD(this, kValueOffset, val);
1192}
1193
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001194
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001195int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001196 InstanceType type = map()->instance_type();
1197 // Check for the most common kind of JavaScript object before
1198 // falling into the generic switch. This speeds up the internal
1199 // field operations considerably on average.
1200 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1201 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001202 case JS_GLOBAL_PROXY_TYPE:
1203 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001204 case JS_GLOBAL_OBJECT_TYPE:
1205 return JSGlobalObject::kSize;
1206 case JS_BUILTINS_OBJECT_TYPE:
1207 return JSBuiltinsObject::kSize;
1208 case JS_FUNCTION_TYPE:
1209 return JSFunction::kSize;
1210 case JS_VALUE_TYPE:
1211 return JSValue::kSize;
1212 case JS_ARRAY_TYPE:
1213 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001214 case JS_REGEXP_TYPE:
1215 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001216 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001217 return JSObject::kHeaderSize;
1218 default:
1219 UNREACHABLE();
1220 return 0;
1221 }
1222}
1223
1224
1225int JSObject::GetInternalFieldCount() {
1226 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001227 // Make sure to adjust for the number of in-object properties. These
1228 // properties do contribute to the size, but are not internal fields.
1229 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1230 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001231}
1232
1233
1234Object* JSObject::GetInternalField(int index) {
1235 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001236 // Internal objects do follow immediately after the header, whereas in-object
1237 // properties are at the end of the object. Therefore there is no need
1238 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001239 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1240}
1241
1242
1243void JSObject::SetInternalField(int index, Object* value) {
1244 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001245 // Internal objects do follow immediately after the header, whereas in-object
1246 // properties are at the end of the object. Therefore there is no need
1247 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001248 int offset = GetHeaderSize() + (kPointerSize * index);
1249 WRITE_FIELD(this, offset, value);
1250 WRITE_BARRIER(this, offset);
1251}
1252
1253
ager@chromium.org7c537e22008-10-16 08:43:32 +00001254// Access fast-case object properties at index. The use of these routines
1255// is needed to correctly distinguish between properties stored in-object and
1256// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001257Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001258 // Adjust for the number of properties stored in the object.
1259 index -= map()->inobject_properties();
1260 if (index < 0) {
1261 int offset = map()->instance_size() + (index * kPointerSize);
1262 return READ_FIELD(this, offset);
1263 } else {
1264 ASSERT(index < properties()->length());
1265 return properties()->get(index);
1266 }
1267}
1268
1269
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001270Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001271 // Adjust for the number of properties stored in the object.
1272 index -= map()->inobject_properties();
1273 if (index < 0) {
1274 int offset = map()->instance_size() + (index * kPointerSize);
1275 WRITE_FIELD(this, offset, value);
1276 WRITE_BARRIER(this, offset);
1277 } else {
1278 ASSERT(index < properties()->length());
1279 properties()->set(index, value);
1280 }
1281 return value;
1282}
1283
1284
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001285Object* JSObject::InObjectPropertyAt(int index) {
1286 // Adjust for the number of properties stored in the object.
1287 index -= map()->inobject_properties();
1288 ASSERT(index < 0);
1289 int offset = map()->instance_size() + (index * kPointerSize);
1290 return READ_FIELD(this, offset);
1291}
1292
1293
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001294Object* JSObject::InObjectPropertyAtPut(int index,
1295 Object* value,
1296 WriteBarrierMode mode) {
1297 // Adjust for the number of properties stored in the object.
1298 index -= map()->inobject_properties();
1299 ASSERT(index < 0);
1300 int offset = map()->instance_size() + (index * kPointerSize);
1301 WRITE_FIELD(this, offset, value);
1302 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1303 return value;
1304}
1305
1306
1307
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001308void JSObject::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001309 Object* value = Heap::undefined_value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001310 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001311 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001312 }
1313}
1314
1315
1316void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001317 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001318 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001319 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001320 }
1321}
1322
1323
1324bool JSObject::HasFastProperties() {
1325 return !properties()->IsDictionary();
1326}
1327
1328
1329bool Array::IndexFromObject(Object* object, uint32_t* index) {
1330 if (object->IsSmi()) {
1331 int value = Smi::cast(object)->value();
1332 if (value < 0) return false;
1333 *index = value;
1334 return true;
1335 }
1336 if (object->IsHeapNumber()) {
1337 double value = HeapNumber::cast(object)->value();
1338 uint32_t uint_value = static_cast<uint32_t>(value);
1339 if (value == static_cast<double>(uint_value)) {
1340 *index = uint_value;
1341 return true;
1342 }
1343 }
1344 return false;
1345}
1346
1347
1348bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1349 if (!this->IsJSValue()) return false;
1350
1351 JSValue* js_value = JSValue::cast(this);
1352 if (!js_value->value()->IsString()) return false;
1353
1354 String* str = String::cast(js_value->value());
1355 if (index >= (uint32_t)str->length()) return false;
1356
1357 return true;
1358}
1359
1360
1361Object* FixedArray::get(int index) {
1362 ASSERT(index >= 0 && index < this->length());
1363 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1364}
1365
1366
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001367void FixedArray::set(int index, Smi* value) {
1368 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1369 int offset = kHeaderSize + index * kPointerSize;
1370 WRITE_FIELD(this, offset, value);
1371}
1372
1373
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001374void FixedArray::set(int index, Object* value) {
1375 ASSERT(index >= 0 && index < this->length());
1376 int offset = kHeaderSize + index * kPointerSize;
1377 WRITE_FIELD(this, offset, value);
1378 WRITE_BARRIER(this, offset);
1379}
1380
1381
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001382WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001383 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1384 return UPDATE_WRITE_BARRIER;
1385}
1386
1387
1388void FixedArray::set(int index,
1389 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001390 WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001391 ASSERT(index >= 0 && index < this->length());
1392 int offset = kHeaderSize + index * kPointerSize;
1393 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001394 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001395}
1396
1397
1398void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
1399 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001400 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001401 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1402}
1403
1404
1405void FixedArray::set_undefined(int index) {
1406 ASSERT(index >= 0 && index < this->length());
1407 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1408 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1409 Heap::undefined_value());
1410}
1411
1412
ager@chromium.org236ad962008-09-25 09:45:57 +00001413void FixedArray::set_null(int index) {
1414 ASSERT(index >= 0 && index < this->length());
1415 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1416 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1417}
1418
1419
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001420void FixedArray::set_the_hole(int index) {
1421 ASSERT(index >= 0 && index < this->length());
1422 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1423 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1424}
1425
1426
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001427Object** FixedArray::data_start() {
1428 return HeapObject::RawField(this, kHeaderSize);
1429}
1430
1431
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001432bool DescriptorArray::IsEmpty() {
1433 ASSERT(this == Heap::empty_descriptor_array() ||
1434 this->length() > 2);
1435 return this == Heap::empty_descriptor_array();
1436}
1437
1438
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001439void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1440 Object* tmp = array->get(first);
1441 fast_set(array, first, array->get(second));
1442 fast_set(array, second, tmp);
1443}
1444
1445
1446int DescriptorArray::Search(String* name) {
1447 SLOW_ASSERT(IsSortedNoDuplicates());
1448
1449 // Check for empty descriptor array.
1450 int nof = number_of_descriptors();
1451 if (nof == 0) return kNotFound;
1452
1453 // Fast case: do linear search for small arrays.
1454 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001455 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001456 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001457 }
1458
1459 // Slow case: perform binary search.
1460 return BinarySearch(name, 0, nof - 1);
1461}
1462
1463
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001464String* DescriptorArray::GetKey(int descriptor_number) {
1465 ASSERT(descriptor_number < number_of_descriptors());
1466 return String::cast(get(ToKeyIndex(descriptor_number)));
1467}
1468
1469
1470Object* DescriptorArray::GetValue(int descriptor_number) {
1471 ASSERT(descriptor_number < number_of_descriptors());
1472 return GetContentArray()->get(ToValueIndex(descriptor_number));
1473}
1474
1475
1476Smi* DescriptorArray::GetDetails(int descriptor_number) {
1477 ASSERT(descriptor_number < number_of_descriptors());
1478 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1479}
1480
1481
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001482PropertyType DescriptorArray::GetType(int descriptor_number) {
1483 ASSERT(descriptor_number < number_of_descriptors());
1484 return PropertyDetails(GetDetails(descriptor_number)).type();
1485}
1486
1487
1488int DescriptorArray::GetFieldIndex(int descriptor_number) {
1489 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1490}
1491
1492
1493JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1494 return JSFunction::cast(GetValue(descriptor_number));
1495}
1496
1497
1498Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1499 ASSERT(GetType(descriptor_number) == CALLBACKS);
1500 return GetValue(descriptor_number);
1501}
1502
1503
1504AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1505 ASSERT(GetType(descriptor_number) == CALLBACKS);
1506 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1507 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1508}
1509
1510
1511bool DescriptorArray::IsProperty(int descriptor_number) {
1512 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1513}
1514
1515
1516bool DescriptorArray::IsTransition(int descriptor_number) {
1517 PropertyType t = GetType(descriptor_number);
1518 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
1519}
1520
1521
1522bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1523 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1524}
1525
1526
1527bool DescriptorArray::IsDontEnum(int descriptor_number) {
1528 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1529}
1530
1531
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001532void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1533 desc->Init(GetKey(descriptor_number),
1534 GetValue(descriptor_number),
1535 GetDetails(descriptor_number));
1536}
1537
1538
1539void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1540 // Range check.
1541 ASSERT(descriptor_number < number_of_descriptors());
1542
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001543 // Make sure none of the elements in desc are in new space.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001544 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1545 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1546
1547 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1548 FixedArray* content_array = GetContentArray();
1549 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1550 fast_set(content_array, ToDetailsIndex(descriptor_number),
1551 desc->GetDetails().AsSmi());
1552}
1553
1554
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001555void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1556 Descriptor desc;
1557 src->Get(src_index, &desc);
1558 Set(index, &desc);
1559}
1560
1561
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001562void DescriptorArray::Swap(int first, int second) {
1563 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1564 FixedArray* content_array = GetContentArray();
1565 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1566 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1567}
1568
1569
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001570bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001571 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001572 if (!max_index_object->IsSmi()) return false;
1573 return 0 !=
1574 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1575}
1576
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001577uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001578 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001579 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001580 if (!max_index_object->IsSmi()) return 0;
1581 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1582 return value >> kRequiresSlowElementsTagSize;
1583}
1584
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001585void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001586 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001587}
1588
1589
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001590// ------------------------------------
1591// Cast operations
1592
1593
1594CAST_ACCESSOR(FixedArray)
1595CAST_ACCESSOR(DescriptorArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001596CAST_ACCESSOR(SymbolTable)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001597CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001598CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001599CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001600CAST_ACCESSOR(String)
1601CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001602CAST_ACCESSOR(SeqAsciiString)
1603CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001604CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001605CAST_ACCESSOR(ExternalString)
1606CAST_ACCESSOR(ExternalAsciiString)
1607CAST_ACCESSOR(ExternalTwoByteString)
1608CAST_ACCESSOR(JSObject)
1609CAST_ACCESSOR(Smi)
1610CAST_ACCESSOR(Failure)
1611CAST_ACCESSOR(HeapObject)
1612CAST_ACCESSOR(HeapNumber)
1613CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001614CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001615CAST_ACCESSOR(SharedFunctionInfo)
1616CAST_ACCESSOR(Map)
1617CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001618CAST_ACCESSOR(GlobalObject)
1619CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001620CAST_ACCESSOR(JSGlobalObject)
1621CAST_ACCESSOR(JSBuiltinsObject)
1622CAST_ACCESSOR(Code)
1623CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001624CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001625CAST_ACCESSOR(Proxy)
1626CAST_ACCESSOR(ByteArray)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001627CAST_ACCESSOR(PixelArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001628CAST_ACCESSOR(ExternalArray)
1629CAST_ACCESSOR(ExternalByteArray)
1630CAST_ACCESSOR(ExternalUnsignedByteArray)
1631CAST_ACCESSOR(ExternalShortArray)
1632CAST_ACCESSOR(ExternalUnsignedShortArray)
1633CAST_ACCESSOR(ExternalIntArray)
1634CAST_ACCESSOR(ExternalUnsignedIntArray)
1635CAST_ACCESSOR(ExternalFloatArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001636CAST_ACCESSOR(Struct)
1637
1638
1639#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1640 STRUCT_LIST(MAKE_STRUCT_CAST)
1641#undef MAKE_STRUCT_CAST
1642
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001643
1644template <typename Shape, typename Key>
1645HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001646 ASSERT(obj->IsHashTable());
1647 return reinterpret_cast<HashTable*>(obj);
1648}
1649
1650
1651INT_ACCESSORS(Array, length, kLengthOffset)
1652
1653
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001654INT_ACCESSORS(String, length, kLengthOffset)
1655
1656
1657uint32_t String::hash_field() {
1658 return READ_UINT32_FIELD(this, kHashFieldOffset);
1659}
1660
1661
1662void String::set_hash_field(uint32_t value) {
1663 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
1664}
1665
1666
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001667bool String::Equals(String* other) {
1668 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001669 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1670 return false;
1671 }
1672 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001673}
1674
1675
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001676Object* String::TryFlatten(PretenureFlag pretenure) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001677 // We don't need to flatten strings that are already flat. Since this code
1678 // is inlined, it can be helpful in the flat case to not call out to Flatten.
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001679 if (IsFlat()) return this;
1680 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001681}
1682
1683
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001684uint16_t String::Get(int index) {
1685 ASSERT(index >= 0 && index < length());
1686 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001687 case kSeqStringTag | kAsciiStringTag:
1688 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1689 case kSeqStringTag | kTwoByteStringTag:
1690 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1691 case kConsStringTag | kAsciiStringTag:
1692 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001693 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001694 case kExternalStringTag | kAsciiStringTag:
1695 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1696 case kExternalStringTag | kTwoByteStringTag:
1697 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001698 default:
1699 break;
1700 }
1701
1702 UNREACHABLE();
1703 return 0;
1704}
1705
1706
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001707void String::Set(int index, uint16_t value) {
1708 ASSERT(index >= 0 && index < length());
1709 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001710
ager@chromium.org5ec48922009-05-05 07:25:34 +00001711 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001712 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1713 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001714}
1715
1716
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001717bool String::IsFlat() {
1718 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001719 case kConsStringTag: {
1720 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001721 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001722 return second->length() == 0;
1723 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001724 default:
1725 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001726 }
1727}
1728
1729
ager@chromium.org7c537e22008-10-16 08:43:32 +00001730uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001731 ASSERT(index >= 0 && index < length());
1732 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1733}
1734
1735
ager@chromium.org7c537e22008-10-16 08:43:32 +00001736void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001737 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1738 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1739 static_cast<byte>(value));
1740}
1741
1742
ager@chromium.org7c537e22008-10-16 08:43:32 +00001743Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001744 return FIELD_ADDR(this, kHeaderSize);
1745}
1746
1747
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001748char* SeqAsciiString::GetChars() {
1749 return reinterpret_cast<char*>(GetCharsAddress());
1750}
1751
1752
ager@chromium.org7c537e22008-10-16 08:43:32 +00001753Address SeqTwoByteString::GetCharsAddress() {
1754 return FIELD_ADDR(this, kHeaderSize);
1755}
1756
1757
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001758uc16* SeqTwoByteString::GetChars() {
1759 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1760}
1761
1762
ager@chromium.org7c537e22008-10-16 08:43:32 +00001763uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001764 ASSERT(index >= 0 && index < length());
1765 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1766}
1767
1768
ager@chromium.org7c537e22008-10-16 08:43:32 +00001769void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001770 ASSERT(index >= 0 && index < length());
1771 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1772}
1773
1774
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001775int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001776 uint32_t length = READ_INT_FIELD(this, kLengthOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001777 return SizeFor(length);
1778}
1779
1780
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001781int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001782 uint32_t length = READ_INT_FIELD(this, kLengthOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001783 return SizeFor(length);
1784}
1785
1786
ager@chromium.org870a0b62008-11-04 11:43:05 +00001787String* ConsString::first() {
1788 return String::cast(READ_FIELD(this, kFirstOffset));
1789}
1790
1791
1792Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001793 return READ_FIELD(this, kFirstOffset);
1794}
1795
1796
ager@chromium.org870a0b62008-11-04 11:43:05 +00001797void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001798 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001799 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001800}
1801
1802
ager@chromium.org870a0b62008-11-04 11:43:05 +00001803String* ConsString::second() {
1804 return String::cast(READ_FIELD(this, kSecondOffset));
1805}
1806
1807
1808Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001809 return READ_FIELD(this, kSecondOffset);
1810}
1811
1812
ager@chromium.org870a0b62008-11-04 11:43:05 +00001813void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001814 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001815 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001816}
1817
1818
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001819ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1820 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1821}
1822
1823
1824void ExternalAsciiString::set_resource(
1825 ExternalAsciiString::Resource* resource) {
1826 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1827}
1828
1829
1830ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1831 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1832}
1833
1834
1835void ExternalTwoByteString::set_resource(
1836 ExternalTwoByteString::Resource* resource) {
1837 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1838}
1839
1840
1841byte ByteArray::get(int index) {
1842 ASSERT(index >= 0 && index < this->length());
1843 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1844}
1845
1846
1847void ByteArray::set(int index, byte value) {
1848 ASSERT(index >= 0 && index < this->length());
1849 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
1850}
1851
1852
1853int ByteArray::get_int(int index) {
1854 ASSERT(index >= 0 && (index * kIntSize) < this->length());
1855 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
1856}
1857
1858
1859ByteArray* ByteArray::FromDataStartAddress(Address address) {
1860 ASSERT_TAG_ALIGNED(address);
1861 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
1862}
1863
1864
1865Address ByteArray::GetDataStartAddress() {
1866 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
1867}
1868
1869
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001870uint8_t* PixelArray::external_pointer() {
1871 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1872 return reinterpret_cast<uint8_t*>(ptr);
1873}
1874
1875
1876void PixelArray::set_external_pointer(uint8_t* value, WriteBarrierMode mode) {
1877 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1878 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1879}
1880
1881
1882uint8_t PixelArray::get(int index) {
1883 ASSERT((index >= 0) && (index < this->length()));
1884 uint8_t* ptr = external_pointer();
1885 return ptr[index];
1886}
1887
1888
1889void PixelArray::set(int index, uint8_t value) {
1890 ASSERT((index >= 0) && (index < this->length()));
1891 uint8_t* ptr = external_pointer();
1892 ptr[index] = value;
1893}
1894
1895
ager@chromium.org3811b432009-10-28 14:53:37 +00001896void* ExternalArray::external_pointer() {
1897 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
1898 return reinterpret_cast<void*>(ptr);
1899}
1900
1901
1902void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
1903 intptr_t ptr = reinterpret_cast<intptr_t>(value);
1904 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
1905}
1906
1907
1908int8_t ExternalByteArray::get(int index) {
1909 ASSERT((index >= 0) && (index < this->length()));
1910 int8_t* ptr = static_cast<int8_t*>(external_pointer());
1911 return ptr[index];
1912}
1913
1914
1915void ExternalByteArray::set(int index, int8_t value) {
1916 ASSERT((index >= 0) && (index < this->length()));
1917 int8_t* ptr = static_cast<int8_t*>(external_pointer());
1918 ptr[index] = value;
1919}
1920
1921
1922uint8_t ExternalUnsignedByteArray::get(int index) {
1923 ASSERT((index >= 0) && (index < this->length()));
1924 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
1925 return ptr[index];
1926}
1927
1928
1929void ExternalUnsignedByteArray::set(int index, uint8_t value) {
1930 ASSERT((index >= 0) && (index < this->length()));
1931 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
1932 ptr[index] = value;
1933}
1934
1935
1936int16_t ExternalShortArray::get(int index) {
1937 ASSERT((index >= 0) && (index < this->length()));
1938 int16_t* ptr = static_cast<int16_t*>(external_pointer());
1939 return ptr[index];
1940}
1941
1942
1943void ExternalShortArray::set(int index, int16_t value) {
1944 ASSERT((index >= 0) && (index < this->length()));
1945 int16_t* ptr = static_cast<int16_t*>(external_pointer());
1946 ptr[index] = value;
1947}
1948
1949
1950uint16_t ExternalUnsignedShortArray::get(int index) {
1951 ASSERT((index >= 0) && (index < this->length()));
1952 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
1953 return ptr[index];
1954}
1955
1956
1957void ExternalUnsignedShortArray::set(int index, uint16_t value) {
1958 ASSERT((index >= 0) && (index < this->length()));
1959 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
1960 ptr[index] = value;
1961}
1962
1963
1964int32_t ExternalIntArray::get(int index) {
1965 ASSERT((index >= 0) && (index < this->length()));
1966 int32_t* ptr = static_cast<int32_t*>(external_pointer());
1967 return ptr[index];
1968}
1969
1970
1971void ExternalIntArray::set(int index, int32_t value) {
1972 ASSERT((index >= 0) && (index < this->length()));
1973 int32_t* ptr = static_cast<int32_t*>(external_pointer());
1974 ptr[index] = value;
1975}
1976
1977
1978uint32_t ExternalUnsignedIntArray::get(int index) {
1979 ASSERT((index >= 0) && (index < this->length()));
1980 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
1981 return ptr[index];
1982}
1983
1984
1985void ExternalUnsignedIntArray::set(int index, uint32_t value) {
1986 ASSERT((index >= 0) && (index < this->length()));
1987 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
1988 ptr[index] = value;
1989}
1990
1991
1992float ExternalFloatArray::get(int index) {
1993 ASSERT((index >= 0) && (index < this->length()));
1994 float* ptr = static_cast<float*>(external_pointer());
1995 return ptr[index];
1996}
1997
1998
1999void ExternalFloatArray::set(int index, float value) {
2000 ASSERT((index >= 0) && (index < this->length()));
2001 float* ptr = static_cast<float*>(external_pointer());
2002 ptr[index] = value;
2003}
2004
2005
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002006int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002007 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2008}
2009
2010
2011int Map::inobject_properties() {
2012 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002013}
2014
2015
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002016int Map::pre_allocated_property_fields() {
2017 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2018}
2019
2020
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002021int HeapObject::SizeFromMap(Map* map) {
2022 InstanceType instance_type = map->instance_type();
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002023 // Only inline the most frequent cases.
2024 if (instance_type == JS_OBJECT_TYPE ||
2025 (instance_type & (kIsNotStringMask | kStringRepresentationMask)) ==
2026 (kStringTag | kConsStringTag) ||
2027 instance_type == JS_ARRAY_TYPE) return map->instance_size();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002028 if (instance_type == FIXED_ARRAY_TYPE) {
2029 return reinterpret_cast<FixedArray*>(this)->FixedArraySize();
2030 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002031 if (instance_type == BYTE_ARRAY_TYPE) {
2032 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2033 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002034 // Otherwise do the general size computation.
2035 return SlowSizeFromMap(map);
2036}
2037
2038
2039void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002040 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002041 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002042 ASSERT(0 <= value && value < 256);
2043 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2044}
2045
2046
ager@chromium.org7c537e22008-10-16 08:43:32 +00002047void Map::set_inobject_properties(int value) {
2048 ASSERT(0 <= value && value < 256);
2049 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2050}
2051
2052
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002053void Map::set_pre_allocated_property_fields(int value) {
2054 ASSERT(0 <= value && value < 256);
2055 WRITE_BYTE_FIELD(this,
2056 kPreAllocatedPropertyFieldsOffset,
2057 static_cast<byte>(value));
2058}
2059
2060
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002061InstanceType Map::instance_type() {
2062 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2063}
2064
2065
2066void Map::set_instance_type(InstanceType value) {
2067 ASSERT(0 <= value && value < 256);
2068 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2069}
2070
2071
2072int Map::unused_property_fields() {
2073 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2074}
2075
2076
2077void Map::set_unused_property_fields(int value) {
2078 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2079}
2080
2081
2082byte Map::bit_field() {
2083 return READ_BYTE_FIELD(this, kBitFieldOffset);
2084}
2085
2086
2087void Map::set_bit_field(byte value) {
2088 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2089}
2090
2091
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002092byte Map::bit_field2() {
2093 return READ_BYTE_FIELD(this, kBitField2Offset);
2094}
2095
2096
2097void Map::set_bit_field2(byte value) {
2098 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2099}
2100
2101
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002102void Map::set_non_instance_prototype(bool value) {
2103 if (value) {
2104 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2105 } else {
2106 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2107 }
2108}
2109
2110
2111bool Map::has_non_instance_prototype() {
2112 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2113}
2114
2115
ager@chromium.org870a0b62008-11-04 11:43:05 +00002116void Map::set_is_access_check_needed(bool access_check_needed) {
2117 if (access_check_needed) {
2118 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2119 } else {
2120 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2121 }
2122}
2123
2124
2125bool Map::is_access_check_needed() {
2126 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2127}
2128
2129
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002130Code::Flags Code::flags() {
2131 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2132}
2133
2134
2135void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002136 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002137 // Make sure that all call stubs have an arguments count.
2138 ASSERT(ExtractKindFromFlags(flags) != CALL_IC ||
2139 ExtractArgumentsCountFromFlags(flags) >= 0);
2140 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2141}
2142
2143
2144Code::Kind Code::kind() {
2145 return ExtractKindFromFlags(flags());
2146}
2147
2148
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002149InLoopFlag Code::ic_in_loop() {
2150 return ExtractICInLoopFromFlags(flags());
2151}
2152
2153
kasper.lund7276f142008-07-30 08:49:36 +00002154InlineCacheState Code::ic_state() {
2155 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002156 // Only allow uninitialized or debugger states for non-IC code
2157 // objects. This is used in the debugger to determine whether or not
2158 // a call to code object has been replaced with a debug break call.
2159 ASSERT(is_inline_cache_stub() ||
2160 result == UNINITIALIZED ||
2161 result == DEBUG_BREAK ||
2162 result == DEBUG_PREPARE_STEP_IN);
2163 return result;
2164}
2165
2166
2167PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002168 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002169 return ExtractTypeFromFlags(flags());
2170}
2171
2172
2173int Code::arguments_count() {
2174 ASSERT(is_call_stub() || kind() == STUB);
2175 return ExtractArgumentsCountFromFlags(flags());
2176}
2177
2178
2179CodeStub::Major Code::major_key() {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002180 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002181 return static_cast<CodeStub::Major>(READ_BYTE_FIELD(this,
2182 kStubMajorKeyOffset));
2183}
2184
2185
2186void Code::set_major_key(CodeStub::Major major) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002187 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002188 ASSERT(0 <= major && major < 256);
2189 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002190}
2191
2192
2193bool Code::is_inline_cache_stub() {
2194 Kind kind = this->kind();
2195 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2196}
2197
2198
2199Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002200 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002201 InlineCacheState ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002202 PropertyType type,
2203 int argc) {
2204 // Compute the bit mask.
2205 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002206 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002207 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002208 bits |= type << kFlagsTypeShift;
2209 bits |= argc << kFlagsArgumentsCountShift;
2210 // Cast to flags and validate result before returning it.
2211 Flags result = static_cast<Flags>(bits);
2212 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002213 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002214 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002215 ASSERT(ExtractTypeFromFlags(result) == type);
2216 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2217 return result;
2218}
2219
2220
2221Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2222 PropertyType type,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002223 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002224 int argc) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002225 return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002226}
2227
2228
2229Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2230 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2231 return static_cast<Kind>(bits);
2232}
2233
2234
kasper.lund7276f142008-07-30 08:49:36 +00002235InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2236 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002237 return static_cast<InlineCacheState>(bits);
2238}
2239
2240
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002241InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2242 int bits = (flags & kFlagsICInLoopMask);
2243 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2244}
2245
2246
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002247PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2248 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2249 return static_cast<PropertyType>(bits);
2250}
2251
2252
2253int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2254 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2255}
2256
2257
2258Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2259 int bits = flags & ~kFlagsTypeMask;
2260 return static_cast<Flags>(bits);
2261}
2262
2263
ager@chromium.org8bb60582008-12-11 12:02:20 +00002264Code* Code::GetCodeFromTargetAddress(Address address) {
2265 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2266 // GetCodeFromTargetAddress might be called when marking objects during mark
2267 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2268 // Code::cast. Code::cast does not work when the object's map is
2269 // marked.
2270 Code* result = reinterpret_cast<Code*>(code);
2271 return result;
2272}
2273
2274
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002275Object* Map::prototype() {
2276 return READ_FIELD(this, kPrototypeOffset);
2277}
2278
2279
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002280void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002281 ASSERT(value->IsNull() || value->IsJSObject());
2282 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002283 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002284}
2285
2286
2287ACCESSORS(Map, instance_descriptors, DescriptorArray,
2288 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002289ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002290ACCESSORS(Map, constructor, Object, kConstructorOffset)
2291
2292ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2293ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
2294
2295ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2296ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002297ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002298
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002299ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002300
2301ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2302ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2303ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2304ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2305ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002306ACCESSORS(AccessorInfo, load_stub_cache, Object, kLoadStubCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002307
2308ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2309ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2310ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2311
2312ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2313ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2314ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2315ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2316ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2317ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2318
2319ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2320ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2321
2322ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2323ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2324
2325ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2326ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002327ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2328 kPropertyAccessorsOffset)
2329ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2330 kPrototypeTemplateOffset)
2331ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2332ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2333 kNamedPropertyHandlerOffset)
2334ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2335 kIndexedPropertyHandlerOffset)
2336ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2337 kInstanceTemplateOffset)
2338ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2339ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002340ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2341 kInstanceCallHandlerOffset)
2342ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2343 kAccessCheckInfoOffset)
2344ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2345
2346ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002347ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2348 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002349
2350ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2351ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2352
2353ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2354
2355ACCESSORS(Script, source, Object, kSourceOffset)
2356ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002357ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002358ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2359ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002360ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002361ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002362ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2363ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002364ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00002365ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002366ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002367ACCESSORS(Script, eval_from_instructions_offset, Smi,
2368 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002369
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002370#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002371ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2372ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2373ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2374ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2375
2376ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2377ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2378ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2379ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002380#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002381
2382ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002383ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002384ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2385 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002386ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002387ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2388ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002389ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002390ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2391 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002392
2393BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2394 kHiddenPrototypeBit)
2395BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2396BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2397 kNeedsAccessCheckBit)
2398BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2399 kIsExpressionBit)
2400BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2401 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002402BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002403 has_only_simple_this_property_assignments,
2404 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002405BOOL_ACCESSORS(SharedFunctionInfo,
2406 compiler_hints,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002407 try_full_codegen,
2408 kTryFullCodegen)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002409
2410INT_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2411INT_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
2412 kFormalParameterCountOffset)
2413INT_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
2414 kExpectedNofPropertiesOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002415INT_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002416INT_ACCESSORS(SharedFunctionInfo, start_position_and_type,
2417 kStartPositionAndTypeOffset)
2418INT_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2419INT_ACCESSORS(SharedFunctionInfo, function_token_position,
2420 kFunctionTokenPositionOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002421INT_ACCESSORS(SharedFunctionInfo, compiler_hints,
2422 kCompilerHintsOffset)
2423INT_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
2424 kThisPropertyAssignmentsCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002425
2426
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002427ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
2428ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
2429
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00002430bool Script::HasValidSource() {
2431 Object* src = this->source();
2432 if (!src->IsString()) return true;
2433 String* src_str = String::cast(src);
2434 if (!StringShape(src_str).IsExternal()) return true;
2435 if (src_str->IsAsciiRepresentation()) {
2436 return ExternalAsciiString::cast(src)->resource() != NULL;
2437 } else if (src_str->IsTwoByteRepresentation()) {
2438 return ExternalTwoByteString::cast(src)->resource() != NULL;
2439 }
2440 return true;
2441}
2442
2443
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002444void SharedFunctionInfo::DontAdaptArguments() {
2445 ASSERT(code()->kind() == Code::BUILTIN);
2446 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2447}
2448
2449
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002450int SharedFunctionInfo::start_position() {
2451 return start_position_and_type() >> kStartPositionShift;
2452}
2453
2454
2455void SharedFunctionInfo::set_start_position(int start_position) {
2456 set_start_position_and_type((start_position << kStartPositionShift)
2457 | (start_position_and_type() & ~kStartPositionMask));
2458}
2459
2460
2461Code* SharedFunctionInfo::code() {
2462 return Code::cast(READ_FIELD(this, kCodeOffset));
2463}
2464
2465
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002466void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002467 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002468 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002469}
2470
2471
2472bool SharedFunctionInfo::is_compiled() {
2473 // TODO(1242782): Create a code kind for uncompiled code.
2474 return code()->kind() != Code::STUB;
2475}
2476
2477
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002478bool SharedFunctionInfo::IsApiFunction() {
2479 return function_data()->IsFunctionTemplateInfo();
2480}
2481
2482
2483FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
2484 ASSERT(IsApiFunction());
2485 return FunctionTemplateInfo::cast(function_data());
2486}
2487
2488
2489bool SharedFunctionInfo::HasCustomCallGenerator() {
2490 return function_data()->IsProxy();
2491}
2492
2493
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002494bool JSFunction::IsBuiltin() {
2495 return context()->global()->IsJSBuiltinsObject();
2496}
2497
2498
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002499Code* JSFunction::code() {
2500 return shared()->code();
2501}
2502
2503
2504void JSFunction::set_code(Code* value) {
2505 shared()->set_code(value);
2506}
2507
2508
2509Context* JSFunction::context() {
2510 return Context::cast(READ_FIELD(this, kContextOffset));
2511}
2512
2513
2514Object* JSFunction::unchecked_context() {
2515 return READ_FIELD(this, kContextOffset);
2516}
2517
2518
2519void JSFunction::set_context(Object* value) {
2520 ASSERT(value == Heap::undefined_value() || value->IsContext());
2521 WRITE_FIELD(this, kContextOffset, value);
2522 WRITE_BARRIER(this, kContextOffset);
2523}
2524
2525ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2526 kPrototypeOrInitialMapOffset)
2527
2528
2529Map* JSFunction::initial_map() {
2530 return Map::cast(prototype_or_initial_map());
2531}
2532
2533
2534void JSFunction::set_initial_map(Map* value) {
2535 set_prototype_or_initial_map(value);
2536}
2537
2538
2539bool JSFunction::has_initial_map() {
2540 return prototype_or_initial_map()->IsMap();
2541}
2542
2543
2544bool JSFunction::has_instance_prototype() {
2545 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2546}
2547
2548
2549bool JSFunction::has_prototype() {
2550 return map()->has_non_instance_prototype() || has_instance_prototype();
2551}
2552
2553
2554Object* JSFunction::instance_prototype() {
2555 ASSERT(has_instance_prototype());
2556 if (has_initial_map()) return initial_map()->prototype();
2557 // When there is no initial map and the prototype is a JSObject, the
2558 // initial map field is used for the prototype field.
2559 return prototype_or_initial_map();
2560}
2561
2562
2563Object* JSFunction::prototype() {
2564 ASSERT(has_prototype());
2565 // If the function's prototype property has been set to a non-JSObject
2566 // value, that value is stored in the constructor field of the map.
2567 if (map()->has_non_instance_prototype()) return map()->constructor();
2568 return instance_prototype();
2569}
2570
2571
2572bool JSFunction::is_compiled() {
2573 return shared()->is_compiled();
2574}
2575
2576
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002577int JSFunction::NumberOfLiterals() {
2578 return literals()->length();
2579}
2580
2581
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002582Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2583 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002584 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002585}
2586
2587
2588void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2589 Object* value) {
2590 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002591 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
2592 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
2593}
2594
2595
2596Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
2597 ASSERT(0 <= id && id < kJSBuiltinsCount);
2598 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
2599}
2600
2601
2602void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
2603 Code* value) {
2604 ASSERT(0 <= id && id < kJSBuiltinsCount);
2605 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
2606 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002607}
2608
2609
2610Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00002611 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002612}
2613
2614
2615void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002616 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002617}
2618
2619
2620void Proxy::ProxyIterateBody(ObjectVisitor* visitor) {
2621 visitor->VisitExternalReference(
2622 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
2623}
2624
2625
2626ACCESSORS(JSValue, value, Object, kValueOffset)
2627
2628
2629JSValue* JSValue::cast(Object* obj) {
2630 ASSERT(obj->IsJSValue());
2631 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2632 return reinterpret_cast<JSValue*>(obj);
2633}
2634
2635
2636INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
2637INT_ACCESSORS(Code, relocation_size, kRelocationSizeOffset)
2638INT_ACCESSORS(Code, sinfo_size, kSInfoSizeOffset)
2639
2640
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002641byte* Code::instruction_start() {
2642 return FIELD_ADDR(this, kHeaderSize);
2643}
2644
2645
2646int Code::body_size() {
2647 return RoundUp(instruction_size() + relocation_size(), kObjectAlignment);
2648}
2649
2650
2651byte* Code::relocation_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002652 return FIELD_ADDR(this, kHeaderSize + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002653}
2654
2655
2656byte* Code::entry() {
2657 return instruction_start();
2658}
2659
2660
2661bool Code::contains(byte* pc) {
2662 return (instruction_start() <= pc) &&
2663 (pc < instruction_start() + instruction_size());
2664}
2665
2666
2667byte* Code::sinfo_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002668 return FIELD_ADDR(this, kHeaderSize + body_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002669}
2670
2671
2672ACCESSORS(JSArray, length, Object, kLengthOffset)
2673
2674
ager@chromium.org236ad962008-09-25 09:45:57 +00002675ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00002676
2677
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002678JSRegExp::Type JSRegExp::TypeTag() {
2679 Object* data = this->data();
2680 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
2681 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
2682 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00002683}
2684
2685
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002686int JSRegExp::CaptureCount() {
2687 switch (TypeTag()) {
2688 case ATOM:
2689 return 0;
2690 case IRREGEXP:
2691 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
2692 default:
2693 UNREACHABLE();
2694 return -1;
2695 }
2696}
2697
2698
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002699JSRegExp::Flags JSRegExp::GetFlags() {
2700 ASSERT(this->data()->IsFixedArray());
2701 Object* data = this->data();
2702 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
2703 return Flags(smi->value());
2704}
2705
2706
2707String* JSRegExp::Pattern() {
2708 ASSERT(this->data()->IsFixedArray());
2709 Object* data = this->data();
2710 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
2711 return pattern;
2712}
2713
2714
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002715Object* JSRegExp::DataAt(int index) {
2716 ASSERT(TypeTag() != NOT_COMPILED);
2717 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00002718}
2719
2720
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002721void JSRegExp::SetDataAt(int index, Object* value) {
2722 ASSERT(TypeTag() != NOT_COMPILED);
2723 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
2724 FixedArray::cast(data())->set(index, value);
2725}
2726
2727
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002728JSObject::ElementsKind JSObject::GetElementsKind() {
2729 Array* array = elements();
2730 if (array->IsFixedArray()) {
2731 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a FixedArray.
2732 if (array->map() == Heap::fixed_array_map()) {
2733 return FAST_ELEMENTS;
2734 }
2735 ASSERT(array->IsDictionary());
2736 return DICTIONARY_ELEMENTS;
2737 }
ager@chromium.org3811b432009-10-28 14:53:37 +00002738 if (array->IsExternalArray()) {
2739 switch (array->map()->instance_type()) {
2740 case EXTERNAL_BYTE_ARRAY_TYPE:
2741 return EXTERNAL_BYTE_ELEMENTS;
2742 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
2743 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2744 case EXTERNAL_SHORT_ARRAY_TYPE:
2745 return EXTERNAL_SHORT_ELEMENTS;
2746 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
2747 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2748 case EXTERNAL_INT_ARRAY_TYPE:
2749 return EXTERNAL_INT_ELEMENTS;
2750 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
2751 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
2752 default:
2753 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
2754 return EXTERNAL_FLOAT_ELEMENTS;
2755 }
2756 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002757 ASSERT(array->IsPixelArray());
2758 return PIXEL_ELEMENTS;
2759}
2760
2761
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002762bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002763 return GetElementsKind() == FAST_ELEMENTS;
2764}
2765
2766
2767bool JSObject::HasDictionaryElements() {
2768 return GetElementsKind() == DICTIONARY_ELEMENTS;
2769}
2770
2771
2772bool JSObject::HasPixelElements() {
2773 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002774}
2775
2776
ager@chromium.org3811b432009-10-28 14:53:37 +00002777bool JSObject::HasExternalArrayElements() {
2778 return (HasExternalByteElements() ||
2779 HasExternalUnsignedByteElements() ||
2780 HasExternalShortElements() ||
2781 HasExternalUnsignedShortElements() ||
2782 HasExternalIntElements() ||
2783 HasExternalUnsignedIntElements() ||
2784 HasExternalFloatElements());
2785}
2786
2787
2788bool JSObject::HasExternalByteElements() {
2789 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
2790}
2791
2792
2793bool JSObject::HasExternalUnsignedByteElements() {
2794 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2795}
2796
2797
2798bool JSObject::HasExternalShortElements() {
2799 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
2800}
2801
2802
2803bool JSObject::HasExternalUnsignedShortElements() {
2804 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2805}
2806
2807
2808bool JSObject::HasExternalIntElements() {
2809 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
2810}
2811
2812
2813bool JSObject::HasExternalUnsignedIntElements() {
2814 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
2815}
2816
2817
2818bool JSObject::HasExternalFloatElements() {
2819 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
2820}
2821
2822
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002823bool JSObject::HasNamedInterceptor() {
2824 return map()->has_named_interceptor();
2825}
2826
2827
2828bool JSObject::HasIndexedInterceptor() {
2829 return map()->has_indexed_interceptor();
2830}
2831
2832
ager@chromium.org5c838252010-02-19 08:53:10 +00002833bool JSObject::AllowsSetElementsLength() {
2834 bool result = elements()->IsFixedArray();
2835 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
2836 return result;
2837}
2838
2839
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002840StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002841 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002842 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002843}
2844
2845
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002846NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002847 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002848 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002849}
2850
2851
2852bool String::HasHashCode() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002853 return (hash_field() & kHashComputedMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002854}
2855
2856
2857uint32_t String::Hash() {
2858 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002859 uint32_t field = hash_field();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002860 if (field & kHashComputedMask) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002861 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002862 return ComputeAndSetHash();
2863}
2864
2865
ager@chromium.org7c537e22008-10-16 08:43:32 +00002866StringHasher::StringHasher(int length)
2867 : length_(length),
2868 raw_running_hash_(0),
2869 array_index_(0),
2870 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
2871 is_first_char_(true),
2872 is_valid_(true) { }
2873
2874
2875bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002876 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00002877}
2878
2879
2880void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002881 // Use the Jenkins one-at-a-time hash function to update the hash
2882 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002883 raw_running_hash_ += c;
2884 raw_running_hash_ += (raw_running_hash_ << 10);
2885 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002886 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002887 if (is_array_index_) {
2888 if (c < '0' || c > '9') {
2889 is_array_index_ = false;
2890 } else {
2891 int d = c - '0';
2892 if (is_first_char_) {
2893 is_first_char_ = false;
2894 if (c == '0' && length_ > 1) {
2895 is_array_index_ = false;
2896 return;
2897 }
2898 }
2899 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
2900 is_array_index_ = false;
2901 } else {
2902 array_index_ = array_index_ * 10 + d;
2903 }
2904 }
2905 }
2906}
2907
2908
2909void StringHasher::AddCharacterNoIndex(uc32 c) {
2910 ASSERT(!is_array_index());
2911 raw_running_hash_ += c;
2912 raw_running_hash_ += (raw_running_hash_ << 10);
2913 raw_running_hash_ ^= (raw_running_hash_ >> 6);
2914}
2915
2916
2917uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002918 // Get the calculated raw hash value and do some more bit ops to distribute
2919 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002920 uint32_t result = raw_running_hash_;
2921 result += (result << 3);
2922 result ^= (result >> 11);
2923 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002924 if (result == 0) {
2925 result = 27;
2926 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002927 return result;
2928}
2929
2930
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002931bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002932 uint32_t field = hash_field();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002933 if ((field & kHashComputedMask) && !(field & kIsArrayIndexMask)) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002934 return SlowAsArrayIndex(index);
2935}
2936
2937
2938Object* JSObject::GetPrototype() {
2939 return JSObject::cast(this)->map()->prototype();
2940}
2941
2942
2943PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
2944 return GetPropertyAttributeWithReceiver(this, key);
2945}
2946
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002947// TODO(504): this may be useful in other places too where JSGlobalProxy
2948// is used.
2949Object* JSObject::BypassGlobalProxy() {
2950 if (IsJSGlobalProxy()) {
2951 Object* proto = GetPrototype();
2952 if (proto->IsNull()) return Heap::undefined_value();
2953 ASSERT(proto->IsJSGlobalObject());
2954 return proto;
2955 }
2956 return this;
2957}
2958
2959
2960bool JSObject::HasHiddenPropertiesObject() {
2961 ASSERT(!IsJSGlobalProxy());
2962 return GetPropertyAttributePostInterceptor(this,
2963 Heap::hidden_symbol(),
2964 false) != ABSENT;
2965}
2966
2967
2968Object* JSObject::GetHiddenPropertiesObject() {
2969 ASSERT(!IsJSGlobalProxy());
2970 PropertyAttributes attributes;
2971 return GetLocalPropertyPostInterceptor(this,
2972 Heap::hidden_symbol(),
2973 &attributes);
2974}
2975
2976
2977Object* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
2978 ASSERT(!IsJSGlobalProxy());
2979 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
2980 hidden_obj,
2981 DONT_ENUM);
2982}
2983
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002984
2985bool JSObject::HasElement(uint32_t index) {
2986 return HasElementWithReceiver(this, index);
2987}
2988
2989
2990bool AccessorInfo::all_can_read() {
2991 return BooleanBit::get(flag(), kAllCanReadBit);
2992}
2993
2994
2995void AccessorInfo::set_all_can_read(bool value) {
2996 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
2997}
2998
2999
3000bool AccessorInfo::all_can_write() {
3001 return BooleanBit::get(flag(), kAllCanWriteBit);
3002}
3003
3004
3005void AccessorInfo::set_all_can_write(bool value) {
3006 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3007}
3008
3009
ager@chromium.org870a0b62008-11-04 11:43:05 +00003010bool AccessorInfo::prohibits_overwriting() {
3011 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3012}
3013
3014
3015void AccessorInfo::set_prohibits_overwriting(bool value) {
3016 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3017}
3018
3019
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003020PropertyAttributes AccessorInfo::property_attributes() {
3021 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3022}
3023
3024
3025void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3026 ASSERT(AttributesField::is_valid(attributes));
3027 int rest_value = flag()->value() & ~AttributesField::mask();
3028 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3029}
3030
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003031template<typename Shape, typename Key>
3032void Dictionary<Shape, Key>::SetEntry(int entry,
3033 Object* key,
3034 Object* value,
3035 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003036 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003037 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003038 AssertNoAllocation no_gc;
3039 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003040 FixedArray::set(index, key, mode);
3041 FixedArray::set(index+1, value, mode);
3042 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003043}
3044
3045
3046void Map::ClearCodeCache() {
3047 // No write barrier is needed since empty_fixed_array is not in new space.
3048 // Please note this function is used during marking:
3049 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003050 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3051 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003052}
3053
3054
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003055void JSArray::EnsureSize(int required_size) {
3056 ASSERT(HasFastElements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003057 Array* elts = elements();
3058 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3059 if (elts->length() < required_size) {
3060 // Doubling in size would be overkill, but leave some slack to avoid
3061 // constantly growing.
3062 Expand(required_size + (required_size >> 3));
3063 // It's a performance benefit to keep a frequently used array in new-space.
3064 } else if (!Heap::new_space()->Contains(elts) &&
3065 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3066 // Expand will allocate a new backing store in new space even if the size
3067 // we asked for isn't larger than what we had before.
3068 Expand(required_size);
3069 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003070}
3071
3072
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003073void JSArray::set_length(Smi* length) {
3074 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3075}
3076
3077
ager@chromium.org7c537e22008-10-16 08:43:32 +00003078void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003079 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003080 set_elements(storage);
3081}
3082
3083
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003084Object* FixedArray::Copy() {
3085 if (length() == 0) return this;
3086 return Heap::CopyFixedArray(this);
3087}
3088
3089
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003090#undef CAST_ACCESSOR
3091#undef INT_ACCESSORS
3092#undef SMI_ACCESSORS
3093#undef ACCESSORS
3094#undef FIELD_ADDR
3095#undef READ_FIELD
3096#undef WRITE_FIELD
3097#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003098#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003099#undef READ_MEMADDR_FIELD
3100#undef WRITE_MEMADDR_FIELD
3101#undef READ_DOUBLE_FIELD
3102#undef WRITE_DOUBLE_FIELD
3103#undef READ_INT_FIELD
3104#undef WRITE_INT_FIELD
3105#undef READ_SHORT_FIELD
3106#undef WRITE_SHORT_FIELD
3107#undef READ_BYTE_FIELD
3108#undef WRITE_BYTE_FIELD
3109
3110
3111} } // namespace v8::internal
3112
3113#endif // V8_OBJECTS_INL_H_