blob: 59fdd86507591a38c062942d2254fc0942d7088a [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
kmillikin@chromium.orgf8253d72010-05-03 09:56:08 +00001654INT_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001655
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) {
kmillikin@chromium.orgf8253d72010-05-03 09:56:08 +00001776 uint32_t length = READ_INT_FIELD(this, kLengthOffset);
1777 return SizeFor(length);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001778}
1779
1780
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001781int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
kmillikin@chromium.orgf8253d72010-05-03 09:56:08 +00001782 uint32_t length = READ_INT_FIELD(this, kLengthOffset);
1783 return SizeFor(length);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001784}
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
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002116void Map::set_function_with_prototype(bool value) {
2117 if (value) {
2118 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2119 } else {
2120 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2121 }
2122}
2123
2124
2125bool Map::function_with_prototype() {
2126 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2127}
2128
2129
ager@chromium.org870a0b62008-11-04 11:43:05 +00002130void Map::set_is_access_check_needed(bool access_check_needed) {
2131 if (access_check_needed) {
2132 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2133 } else {
2134 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2135 }
2136}
2137
2138
2139bool Map::is_access_check_needed() {
2140 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2141}
2142
2143
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002144Code::Flags Code::flags() {
2145 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2146}
2147
2148
2149void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002150 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002151 // Make sure that all call stubs have an arguments count.
2152 ASSERT(ExtractKindFromFlags(flags) != CALL_IC ||
2153 ExtractArgumentsCountFromFlags(flags) >= 0);
2154 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2155}
2156
2157
2158Code::Kind Code::kind() {
2159 return ExtractKindFromFlags(flags());
2160}
2161
2162
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002163InLoopFlag Code::ic_in_loop() {
2164 return ExtractICInLoopFromFlags(flags());
2165}
2166
2167
kasper.lund7276f142008-07-30 08:49:36 +00002168InlineCacheState Code::ic_state() {
2169 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002170 // Only allow uninitialized or debugger states for non-IC code
2171 // objects. This is used in the debugger to determine whether or not
2172 // a call to code object has been replaced with a debug break call.
2173 ASSERT(is_inline_cache_stub() ||
2174 result == UNINITIALIZED ||
2175 result == DEBUG_BREAK ||
2176 result == DEBUG_PREPARE_STEP_IN);
2177 return result;
2178}
2179
2180
2181PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002182 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002183 return ExtractTypeFromFlags(flags());
2184}
2185
2186
2187int Code::arguments_count() {
2188 ASSERT(is_call_stub() || kind() == STUB);
2189 return ExtractArgumentsCountFromFlags(flags());
2190}
2191
2192
2193CodeStub::Major Code::major_key() {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002194 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002195 return static_cast<CodeStub::Major>(READ_BYTE_FIELD(this,
2196 kStubMajorKeyOffset));
2197}
2198
2199
2200void Code::set_major_key(CodeStub::Major major) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002201 ASSERT(kind() == STUB || kind() == BINARY_OP_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002202 ASSERT(0 <= major && major < 256);
2203 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002204}
2205
2206
2207bool Code::is_inline_cache_stub() {
2208 Kind kind = this->kind();
2209 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2210}
2211
2212
2213Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002214 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002215 InlineCacheState ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002216 PropertyType type,
2217 int argc) {
2218 // Compute the bit mask.
2219 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002220 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002221 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002222 bits |= type << kFlagsTypeShift;
2223 bits |= argc << kFlagsArgumentsCountShift;
2224 // Cast to flags and validate result before returning it.
2225 Flags result = static_cast<Flags>(bits);
2226 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002227 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002228 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002229 ASSERT(ExtractTypeFromFlags(result) == type);
2230 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2231 return result;
2232}
2233
2234
2235Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2236 PropertyType type,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002237 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002238 int argc) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002239 return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002240}
2241
2242
2243Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2244 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2245 return static_cast<Kind>(bits);
2246}
2247
2248
kasper.lund7276f142008-07-30 08:49:36 +00002249InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2250 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002251 return static_cast<InlineCacheState>(bits);
2252}
2253
2254
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002255InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2256 int bits = (flags & kFlagsICInLoopMask);
2257 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2258}
2259
2260
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002261PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2262 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2263 return static_cast<PropertyType>(bits);
2264}
2265
2266
2267int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2268 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2269}
2270
2271
2272Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2273 int bits = flags & ~kFlagsTypeMask;
2274 return static_cast<Flags>(bits);
2275}
2276
2277
ager@chromium.org8bb60582008-12-11 12:02:20 +00002278Code* Code::GetCodeFromTargetAddress(Address address) {
2279 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2280 // GetCodeFromTargetAddress might be called when marking objects during mark
2281 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2282 // Code::cast. Code::cast does not work when the object's map is
2283 // marked.
2284 Code* result = reinterpret_cast<Code*>(code);
2285 return result;
2286}
2287
2288
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002289Object* Map::prototype() {
2290 return READ_FIELD(this, kPrototypeOffset);
2291}
2292
2293
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002294void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002295 ASSERT(value->IsNull() || value->IsJSObject());
2296 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002297 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002298}
2299
2300
2301ACCESSORS(Map, instance_descriptors, DescriptorArray,
2302 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002303ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002304ACCESSORS(Map, constructor, Object, kConstructorOffset)
2305
2306ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2307ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
2308
2309ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2310ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002311ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002312
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002313ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002314
2315ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2316ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2317ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2318ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2319ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002320ACCESSORS(AccessorInfo, load_stub_cache, Object, kLoadStubCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002321
2322ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2323ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2324ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2325
2326ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2327ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2328ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2329ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2330ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2331ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2332
2333ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2334ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2335
2336ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2337ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2338
2339ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2340ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002341ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2342 kPropertyAccessorsOffset)
2343ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2344 kPrototypeTemplateOffset)
2345ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2346ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2347 kNamedPropertyHandlerOffset)
2348ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2349 kIndexedPropertyHandlerOffset)
2350ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2351 kInstanceTemplateOffset)
2352ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2353ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002354ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2355 kInstanceCallHandlerOffset)
2356ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2357 kAccessCheckInfoOffset)
2358ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2359
2360ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002361ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2362 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002363
2364ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2365ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2366
2367ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2368
2369ACCESSORS(Script, source, Object, kSourceOffset)
2370ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002371ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002372ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2373ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002374ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002375ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002376ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2377ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002378ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00002379ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00002380ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002381ACCESSORS(Script, eval_from_instructions_offset, Smi,
2382 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002383
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002384#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002385ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2386ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2387ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2388ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2389
2390ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2391ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2392ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2393ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002394#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002395
2396ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002397ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002398ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2399 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002400ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002401ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2402ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002403ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002404ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2405 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002406
2407BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2408 kHiddenPrototypeBit)
2409BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2410BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2411 kNeedsAccessCheckBit)
2412BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2413 kIsExpressionBit)
2414BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2415 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002416BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002417 has_only_simple_this_property_assignments,
2418 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002419BOOL_ACCESSORS(SharedFunctionInfo,
2420 compiler_hints,
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002421 try_full_codegen,
2422 kTryFullCodegen)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002423
2424INT_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2425INT_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
2426 kFormalParameterCountOffset)
2427INT_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
2428 kExpectedNofPropertiesOffset)
kmillikin@chromium.org5d8f0e62010-03-24 08:21:20 +00002429INT_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002430INT_ACCESSORS(SharedFunctionInfo, start_position_and_type,
2431 kStartPositionAndTypeOffset)
2432INT_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2433INT_ACCESSORS(SharedFunctionInfo, function_token_position,
2434 kFunctionTokenPositionOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002435INT_ACCESSORS(SharedFunctionInfo, compiler_hints,
2436 kCompilerHintsOffset)
2437INT_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
2438 kThisPropertyAssignmentsCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002439
2440
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002441ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
2442ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
2443
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00002444bool Script::HasValidSource() {
2445 Object* src = this->source();
2446 if (!src->IsString()) return true;
2447 String* src_str = String::cast(src);
2448 if (!StringShape(src_str).IsExternal()) return true;
2449 if (src_str->IsAsciiRepresentation()) {
2450 return ExternalAsciiString::cast(src)->resource() != NULL;
2451 } else if (src_str->IsTwoByteRepresentation()) {
2452 return ExternalTwoByteString::cast(src)->resource() != NULL;
2453 }
2454 return true;
2455}
2456
2457
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002458void SharedFunctionInfo::DontAdaptArguments() {
2459 ASSERT(code()->kind() == Code::BUILTIN);
2460 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2461}
2462
2463
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002464int SharedFunctionInfo::start_position() {
2465 return start_position_and_type() >> kStartPositionShift;
2466}
2467
2468
2469void SharedFunctionInfo::set_start_position(int start_position) {
2470 set_start_position_and_type((start_position << kStartPositionShift)
2471 | (start_position_and_type() & ~kStartPositionMask));
2472}
2473
2474
2475Code* SharedFunctionInfo::code() {
2476 return Code::cast(READ_FIELD(this, kCodeOffset));
2477}
2478
2479
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002480void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002481 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002482 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002483}
2484
2485
2486bool SharedFunctionInfo::is_compiled() {
2487 // TODO(1242782): Create a code kind for uncompiled code.
2488 return code()->kind() != Code::STUB;
2489}
2490
2491
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00002492bool SharedFunctionInfo::IsApiFunction() {
2493 return function_data()->IsFunctionTemplateInfo();
2494}
2495
2496
2497FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
2498 ASSERT(IsApiFunction());
2499 return FunctionTemplateInfo::cast(function_data());
2500}
2501
2502
2503bool SharedFunctionInfo::HasCustomCallGenerator() {
2504 return function_data()->IsProxy();
2505}
2506
2507
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002508bool JSFunction::IsBuiltin() {
2509 return context()->global()->IsJSBuiltinsObject();
2510}
2511
2512
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002513Code* JSFunction::code() {
2514 return shared()->code();
2515}
2516
2517
2518void JSFunction::set_code(Code* value) {
2519 shared()->set_code(value);
2520}
2521
2522
2523Context* JSFunction::context() {
2524 return Context::cast(READ_FIELD(this, kContextOffset));
2525}
2526
2527
2528Object* JSFunction::unchecked_context() {
2529 return READ_FIELD(this, kContextOffset);
2530}
2531
2532
2533void JSFunction::set_context(Object* value) {
2534 ASSERT(value == Heap::undefined_value() || value->IsContext());
2535 WRITE_FIELD(this, kContextOffset, value);
2536 WRITE_BARRIER(this, kContextOffset);
2537}
2538
2539ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2540 kPrototypeOrInitialMapOffset)
2541
2542
2543Map* JSFunction::initial_map() {
2544 return Map::cast(prototype_or_initial_map());
2545}
2546
2547
2548void JSFunction::set_initial_map(Map* value) {
2549 set_prototype_or_initial_map(value);
2550}
2551
2552
2553bool JSFunction::has_initial_map() {
2554 return prototype_or_initial_map()->IsMap();
2555}
2556
2557
2558bool JSFunction::has_instance_prototype() {
2559 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2560}
2561
2562
2563bool JSFunction::has_prototype() {
2564 return map()->has_non_instance_prototype() || has_instance_prototype();
2565}
2566
2567
2568Object* JSFunction::instance_prototype() {
2569 ASSERT(has_instance_prototype());
2570 if (has_initial_map()) return initial_map()->prototype();
2571 // When there is no initial map and the prototype is a JSObject, the
2572 // initial map field is used for the prototype field.
2573 return prototype_or_initial_map();
2574}
2575
2576
2577Object* JSFunction::prototype() {
2578 ASSERT(has_prototype());
2579 // If the function's prototype property has been set to a non-JSObject
2580 // value, that value is stored in the constructor field of the map.
2581 if (map()->has_non_instance_prototype()) return map()->constructor();
2582 return instance_prototype();
2583}
2584
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002585bool JSFunction::should_have_prototype() {
2586 return map()->function_with_prototype();
2587}
2588
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002589
2590bool JSFunction::is_compiled() {
2591 return shared()->is_compiled();
2592}
2593
2594
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002595int JSFunction::NumberOfLiterals() {
2596 return literals()->length();
2597}
2598
2599
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002600Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2601 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002602 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002603}
2604
2605
2606void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2607 Object* value) {
2608 ASSERT(0 <= id && id < kJSBuiltinsCount);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00002609 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
2610 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
2611}
2612
2613
2614Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
2615 ASSERT(0 <= id && id < kJSBuiltinsCount);
2616 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
2617}
2618
2619
2620void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
2621 Code* value) {
2622 ASSERT(0 <= id && id < kJSBuiltinsCount);
2623 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
2624 ASSERT(!Heap::InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002625}
2626
2627
2628Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00002629 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002630}
2631
2632
2633void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002634 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002635}
2636
2637
2638void Proxy::ProxyIterateBody(ObjectVisitor* visitor) {
2639 visitor->VisitExternalReference(
2640 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
2641}
2642
2643
2644ACCESSORS(JSValue, value, Object, kValueOffset)
2645
2646
2647JSValue* JSValue::cast(Object* obj) {
2648 ASSERT(obj->IsJSValue());
2649 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2650 return reinterpret_cast<JSValue*>(obj);
2651}
2652
2653
2654INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
2655INT_ACCESSORS(Code, relocation_size, kRelocationSizeOffset)
2656INT_ACCESSORS(Code, sinfo_size, kSInfoSizeOffset)
2657
2658
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002659byte* Code::instruction_start() {
2660 return FIELD_ADDR(this, kHeaderSize);
2661}
2662
2663
2664int Code::body_size() {
2665 return RoundUp(instruction_size() + relocation_size(), kObjectAlignment);
2666}
2667
2668
2669byte* Code::relocation_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002670 return FIELD_ADDR(this, kHeaderSize + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002671}
2672
2673
2674byte* Code::entry() {
2675 return instruction_start();
2676}
2677
2678
2679bool Code::contains(byte* pc) {
2680 return (instruction_start() <= pc) &&
2681 (pc < instruction_start() + instruction_size());
2682}
2683
2684
2685byte* Code::sinfo_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002686 return FIELD_ADDR(this, kHeaderSize + body_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002687}
2688
2689
2690ACCESSORS(JSArray, length, Object, kLengthOffset)
2691
2692
ager@chromium.org236ad962008-09-25 09:45:57 +00002693ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00002694
2695
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002696JSRegExp::Type JSRegExp::TypeTag() {
2697 Object* data = this->data();
2698 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
2699 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
2700 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00002701}
2702
2703
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002704int JSRegExp::CaptureCount() {
2705 switch (TypeTag()) {
2706 case ATOM:
2707 return 0;
2708 case IRREGEXP:
2709 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
2710 default:
2711 UNREACHABLE();
2712 return -1;
2713 }
2714}
2715
2716
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002717JSRegExp::Flags JSRegExp::GetFlags() {
2718 ASSERT(this->data()->IsFixedArray());
2719 Object* data = this->data();
2720 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
2721 return Flags(smi->value());
2722}
2723
2724
2725String* JSRegExp::Pattern() {
2726 ASSERT(this->data()->IsFixedArray());
2727 Object* data = this->data();
2728 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
2729 return pattern;
2730}
2731
2732
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002733Object* JSRegExp::DataAt(int index) {
2734 ASSERT(TypeTag() != NOT_COMPILED);
2735 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00002736}
2737
2738
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002739void JSRegExp::SetDataAt(int index, Object* value) {
2740 ASSERT(TypeTag() != NOT_COMPILED);
2741 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
2742 FixedArray::cast(data())->set(index, value);
2743}
2744
2745
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002746JSObject::ElementsKind JSObject::GetElementsKind() {
2747 Array* array = elements();
2748 if (array->IsFixedArray()) {
2749 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a FixedArray.
2750 if (array->map() == Heap::fixed_array_map()) {
2751 return FAST_ELEMENTS;
2752 }
2753 ASSERT(array->IsDictionary());
2754 return DICTIONARY_ELEMENTS;
2755 }
ager@chromium.org3811b432009-10-28 14:53:37 +00002756 if (array->IsExternalArray()) {
2757 switch (array->map()->instance_type()) {
2758 case EXTERNAL_BYTE_ARRAY_TYPE:
2759 return EXTERNAL_BYTE_ELEMENTS;
2760 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
2761 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2762 case EXTERNAL_SHORT_ARRAY_TYPE:
2763 return EXTERNAL_SHORT_ELEMENTS;
2764 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
2765 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2766 case EXTERNAL_INT_ARRAY_TYPE:
2767 return EXTERNAL_INT_ELEMENTS;
2768 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
2769 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
2770 default:
2771 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
2772 return EXTERNAL_FLOAT_ELEMENTS;
2773 }
2774 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002775 ASSERT(array->IsPixelArray());
2776 return PIXEL_ELEMENTS;
2777}
2778
2779
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002780bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002781 return GetElementsKind() == FAST_ELEMENTS;
2782}
2783
2784
2785bool JSObject::HasDictionaryElements() {
2786 return GetElementsKind() == DICTIONARY_ELEMENTS;
2787}
2788
2789
2790bool JSObject::HasPixelElements() {
2791 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002792}
2793
2794
ager@chromium.org3811b432009-10-28 14:53:37 +00002795bool JSObject::HasExternalArrayElements() {
2796 return (HasExternalByteElements() ||
2797 HasExternalUnsignedByteElements() ||
2798 HasExternalShortElements() ||
2799 HasExternalUnsignedShortElements() ||
2800 HasExternalIntElements() ||
2801 HasExternalUnsignedIntElements() ||
2802 HasExternalFloatElements());
2803}
2804
2805
2806bool JSObject::HasExternalByteElements() {
2807 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
2808}
2809
2810
2811bool JSObject::HasExternalUnsignedByteElements() {
2812 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2813}
2814
2815
2816bool JSObject::HasExternalShortElements() {
2817 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
2818}
2819
2820
2821bool JSObject::HasExternalUnsignedShortElements() {
2822 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2823}
2824
2825
2826bool JSObject::HasExternalIntElements() {
2827 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
2828}
2829
2830
2831bool JSObject::HasExternalUnsignedIntElements() {
2832 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
2833}
2834
2835
2836bool JSObject::HasExternalFloatElements() {
2837 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
2838}
2839
2840
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002841bool JSObject::HasNamedInterceptor() {
2842 return map()->has_named_interceptor();
2843}
2844
2845
2846bool JSObject::HasIndexedInterceptor() {
2847 return map()->has_indexed_interceptor();
2848}
2849
2850
ager@chromium.org5c838252010-02-19 08:53:10 +00002851bool JSObject::AllowsSetElementsLength() {
2852 bool result = elements()->IsFixedArray();
2853 ASSERT(result == (!HasPixelElements() && !HasExternalArrayElements()));
2854 return result;
2855}
2856
2857
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002858StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002859 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002860 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002861}
2862
2863
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002864NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002865 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002866 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002867}
2868
2869
2870bool String::HasHashCode() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002871 return (hash_field() & kHashComputedMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002872}
2873
2874
2875uint32_t String::Hash() {
2876 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002877 uint32_t field = hash_field();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002878 if (field & kHashComputedMask) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002879 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002880 return ComputeAndSetHash();
2881}
2882
2883
ager@chromium.org7c537e22008-10-16 08:43:32 +00002884StringHasher::StringHasher(int length)
2885 : length_(length),
2886 raw_running_hash_(0),
2887 array_index_(0),
2888 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
2889 is_first_char_(true),
2890 is_valid_(true) { }
2891
2892
2893bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002894 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00002895}
2896
2897
2898void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002899 // Use the Jenkins one-at-a-time hash function to update the hash
2900 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002901 raw_running_hash_ += c;
2902 raw_running_hash_ += (raw_running_hash_ << 10);
2903 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002904 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002905 if (is_array_index_) {
2906 if (c < '0' || c > '9') {
2907 is_array_index_ = false;
2908 } else {
2909 int d = c - '0';
2910 if (is_first_char_) {
2911 is_first_char_ = false;
2912 if (c == '0' && length_ > 1) {
2913 is_array_index_ = false;
2914 return;
2915 }
2916 }
2917 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
2918 is_array_index_ = false;
2919 } else {
2920 array_index_ = array_index_ * 10 + d;
2921 }
2922 }
2923 }
2924}
2925
2926
2927void StringHasher::AddCharacterNoIndex(uc32 c) {
2928 ASSERT(!is_array_index());
2929 raw_running_hash_ += c;
2930 raw_running_hash_ += (raw_running_hash_ << 10);
2931 raw_running_hash_ ^= (raw_running_hash_ >> 6);
2932}
2933
2934
2935uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002936 // Get the calculated raw hash value and do some more bit ops to distribute
2937 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002938 uint32_t result = raw_running_hash_;
2939 result += (result << 3);
2940 result ^= (result >> 11);
2941 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002942 if (result == 0) {
2943 result = 27;
2944 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002945 return result;
2946}
2947
2948
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002949bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002950 uint32_t field = hash_field();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002951 if ((field & kHashComputedMask) && !(field & kIsArrayIndexMask)) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002952 return SlowAsArrayIndex(index);
2953}
2954
2955
2956Object* JSObject::GetPrototype() {
2957 return JSObject::cast(this)->map()->prototype();
2958}
2959
2960
2961PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
2962 return GetPropertyAttributeWithReceiver(this, key);
2963}
2964
ager@chromium.orgc4c92722009-11-18 14:12:51 +00002965// TODO(504): this may be useful in other places too where JSGlobalProxy
2966// is used.
2967Object* JSObject::BypassGlobalProxy() {
2968 if (IsJSGlobalProxy()) {
2969 Object* proto = GetPrototype();
2970 if (proto->IsNull()) return Heap::undefined_value();
2971 ASSERT(proto->IsJSGlobalObject());
2972 return proto;
2973 }
2974 return this;
2975}
2976
2977
2978bool JSObject::HasHiddenPropertiesObject() {
2979 ASSERT(!IsJSGlobalProxy());
2980 return GetPropertyAttributePostInterceptor(this,
2981 Heap::hidden_symbol(),
2982 false) != ABSENT;
2983}
2984
2985
2986Object* JSObject::GetHiddenPropertiesObject() {
2987 ASSERT(!IsJSGlobalProxy());
2988 PropertyAttributes attributes;
2989 return GetLocalPropertyPostInterceptor(this,
2990 Heap::hidden_symbol(),
2991 &attributes);
2992}
2993
2994
2995Object* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
2996 ASSERT(!IsJSGlobalProxy());
2997 return SetPropertyPostInterceptor(Heap::hidden_symbol(),
2998 hidden_obj,
2999 DONT_ENUM);
3000}
3001
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003002
3003bool JSObject::HasElement(uint32_t index) {
3004 return HasElementWithReceiver(this, index);
3005}
3006
3007
3008bool AccessorInfo::all_can_read() {
3009 return BooleanBit::get(flag(), kAllCanReadBit);
3010}
3011
3012
3013void AccessorInfo::set_all_can_read(bool value) {
3014 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3015}
3016
3017
3018bool AccessorInfo::all_can_write() {
3019 return BooleanBit::get(flag(), kAllCanWriteBit);
3020}
3021
3022
3023void AccessorInfo::set_all_can_write(bool value) {
3024 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3025}
3026
3027
ager@chromium.org870a0b62008-11-04 11:43:05 +00003028bool AccessorInfo::prohibits_overwriting() {
3029 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3030}
3031
3032
3033void AccessorInfo::set_prohibits_overwriting(bool value) {
3034 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3035}
3036
3037
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003038PropertyAttributes AccessorInfo::property_attributes() {
3039 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3040}
3041
3042
3043void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3044 ASSERT(AttributesField::is_valid(attributes));
3045 int rest_value = flag()->value() & ~AttributesField::mask();
3046 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3047}
3048
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003049template<typename Shape, typename Key>
3050void Dictionary<Shape, Key>::SetEntry(int entry,
3051 Object* key,
3052 Object* value,
3053 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003054 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003055 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003056 AssertNoAllocation no_gc;
3057 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003058 FixedArray::set(index, key, mode);
3059 FixedArray::set(index+1, value, mode);
3060 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003061}
3062
3063
3064void Map::ClearCodeCache() {
3065 // No write barrier is needed since empty_fixed_array is not in new space.
3066 // Please note this function is used during marking:
3067 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003068 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3069 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003070}
3071
3072
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003073void JSArray::EnsureSize(int required_size) {
3074 ASSERT(HasFastElements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00003075 Array* elts = elements();
3076 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
3077 if (elts->length() < required_size) {
3078 // Doubling in size would be overkill, but leave some slack to avoid
3079 // constantly growing.
3080 Expand(required_size + (required_size >> 3));
3081 // It's a performance benefit to keep a frequently used array in new-space.
3082 } else if (!Heap::new_space()->Contains(elts) &&
3083 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
3084 // Expand will allocate a new backing store in new space even if the size
3085 // we asked for isn't larger than what we had before.
3086 Expand(required_size);
3087 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003088}
3089
3090
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003091void JSArray::set_length(Smi* length) {
3092 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
3093}
3094
3095
ager@chromium.org7c537e22008-10-16 08:43:32 +00003096void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003097 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00003098 set_elements(storage);
3099}
3100
3101
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003102Object* FixedArray::Copy() {
3103 if (length() == 0) return this;
3104 return Heap::CopyFixedArray(this);
3105}
3106
3107
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003108#undef CAST_ACCESSOR
3109#undef INT_ACCESSORS
3110#undef SMI_ACCESSORS
3111#undef ACCESSORS
3112#undef FIELD_ADDR
3113#undef READ_FIELD
3114#undef WRITE_FIELD
3115#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003116#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003117#undef READ_MEMADDR_FIELD
3118#undef WRITE_MEMADDR_FIELD
3119#undef READ_DOUBLE_FIELD
3120#undef WRITE_DOUBLE_FIELD
3121#undef READ_INT_FIELD
3122#undef WRITE_INT_FIELD
3123#undef READ_SHORT_FIELD
3124#undef WRITE_SHORT_FIELD
3125#undef READ_BYTE_FIELD
3126#undef WRITE_BYTE_FIELD
3127
3128
3129} } // namespace v8::internal
3130
3131#endif // V8_OBJECTS_INL_H_