blob: 5907a86f69ac1ea395b2bd8353e5c6e84b868bcf [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();
153 return (type & (kIsNotStringMask | kIsSymbolMask)) ==
154 (kStringTag | kSymbolTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000155}
156
157
158bool Object::IsConsString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000159 if (!this->IsHeapObject()) return false;
160 uint32_t type = HeapObject::cast(this)->map()->instance_type();
161 return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
162 (kStringTag | kConsStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000163}
164
165
ager@chromium.org870a0b62008-11-04 11:43:05 +0000166#ifdef DEBUG
167// These are for cast checks. If you need one of these in release
168// mode you should consider using a StringShape before moving it out
169// of the ifdef
170
171bool Object::IsSeqString() {
172 if (!IsString()) return false;
173 return StringShape(String::cast(this)).IsSequential();
174}
175
176
177bool Object::IsSeqAsciiString() {
178 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000179 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000180 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000181}
182
183
184bool Object::IsSeqTwoByteString() {
185 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000186 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000187 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000188}
189
190
191bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000192 if (!IsString()) return false;
193 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000194}
195
196
197bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000198 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000199 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000200 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000201}
202
203
204bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000205 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000206 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000207 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000208}
209
210
ager@chromium.org870a0b62008-11-04 11:43:05 +0000211bool Object::IsSlicedString() {
212 if (!IsString()) return false;
213 return StringShape(String::cast(this)).IsSliced();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000214}
215
216
ager@chromium.org870a0b62008-11-04 11:43:05 +0000217#endif // DEBUG
218
219
220StringShape::StringShape(String* str)
221 : type_(str->map()->instance_type()) {
222 set_valid();
223 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000224}
225
226
ager@chromium.org870a0b62008-11-04 11:43:05 +0000227StringShape::StringShape(Map* map)
228 : type_(map->instance_type()) {
229 set_valid();
230 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000231}
232
233
ager@chromium.org870a0b62008-11-04 11:43:05 +0000234StringShape::StringShape(InstanceType t)
235 : type_(static_cast<uint32_t>(t)) {
236 set_valid();
237 ASSERT((type_ & kIsNotStringMask) == kStringTag);
238}
239
240
241bool StringShape::IsSymbol() {
242 ASSERT(valid());
243 return (type_ & kIsSymbolMask) == kSymbolTag;
244}
245
246
ager@chromium.org5ec48922009-05-05 07:25:34 +0000247bool String::IsAsciiRepresentation() {
248 uint32_t type = map()->instance_type();
249 if ((type & kStringRepresentationMask) == kSlicedStringTag) {
250 return SlicedString::cast(this)->buffer()->IsAsciiRepresentation();
251 }
252 if ((type & kStringRepresentationMask) == kConsStringTag &&
253 ConsString::cast(this)->second()->length() == 0) {
254 return ConsString::cast(this)->first()->IsAsciiRepresentation();
255 }
256 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000257}
258
259
ager@chromium.org5ec48922009-05-05 07:25:34 +0000260bool String::IsTwoByteRepresentation() {
261 uint32_t type = map()->instance_type();
262 if ((type & kStringRepresentationMask) == kSlicedStringTag) {
263 return SlicedString::cast(this)->buffer()->IsTwoByteRepresentation();
264 } else if ((type & kStringRepresentationMask) == kConsStringTag &&
265 ConsString::cast(this)->second()->length() == 0) {
266 return ConsString::cast(this)->first()->IsTwoByteRepresentation();
267 }
268 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000269}
270
271
272bool StringShape::IsCons() {
273 return (type_ & kStringRepresentationMask) == kConsStringTag;
274}
275
276
277bool StringShape::IsSliced() {
278 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
279}
280
281
282bool StringShape::IsExternal() {
283 return (type_ & kStringRepresentationMask) == kExternalStringTag;
284}
285
286
287bool StringShape::IsSequential() {
288 return (type_ & kStringRepresentationMask) == kSeqStringTag;
289}
290
291
292StringRepresentationTag StringShape::representation_tag() {
293 uint32_t tag = (type_ & kStringRepresentationMask);
294 return static_cast<StringRepresentationTag>(tag);
295}
296
297
298uint32_t StringShape::full_representation_tag() {
299 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
300}
301
302
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000303STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
304 Internals::kFullStringRepresentationMask);
305
306
ager@chromium.org870a0b62008-11-04 11:43:05 +0000307uint32_t StringShape::size_tag() {
308 return (type_ & kStringSizeMask);
309}
310
311
312bool StringShape::IsSequentialAscii() {
313 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
314}
315
316
317bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000318 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000319}
320
321
322bool StringShape::IsExternalAscii() {
323 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
324}
325
326
327bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000328 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000329}
330
331
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000332STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
333 Internals::kExternalTwoByteRepresentationTag);
334
335
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000336uc32 FlatStringReader::Get(int index) {
337 ASSERT(0 <= index && index <= length_);
338 if (is_ascii_) {
339 return static_cast<const byte*>(start_)[index];
340 } else {
341 return static_cast<const uc16*>(start_)[index];
342 }
343}
344
345
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000346bool Object::IsNumber() {
347 return IsSmi() || IsHeapNumber();
348}
349
350
351bool Object::IsByteArray() {
352 return Object::IsHeapObject()
353 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
354}
355
356
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000357bool Object::IsPixelArray() {
358 return Object::IsHeapObject() &&
359 HeapObject::cast(this)->map()->instance_type() == PIXEL_ARRAY_TYPE;
360}
361
362
ager@chromium.org3811b432009-10-28 14:53:37 +0000363bool Object::IsExternalArray() {
364 if (!Object::IsHeapObject())
365 return false;
366 InstanceType instance_type =
367 HeapObject::cast(this)->map()->instance_type();
368 return (instance_type >= EXTERNAL_BYTE_ARRAY_TYPE &&
369 instance_type <= EXTERNAL_FLOAT_ARRAY_TYPE);
370}
371
372
373bool Object::IsExternalByteArray() {
374 return Object::IsHeapObject() &&
375 HeapObject::cast(this)->map()->instance_type() ==
376 EXTERNAL_BYTE_ARRAY_TYPE;
377}
378
379
380bool Object::IsExternalUnsignedByteArray() {
381 return Object::IsHeapObject() &&
382 HeapObject::cast(this)->map()->instance_type() ==
383 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
384}
385
386
387bool Object::IsExternalShortArray() {
388 return Object::IsHeapObject() &&
389 HeapObject::cast(this)->map()->instance_type() ==
390 EXTERNAL_SHORT_ARRAY_TYPE;
391}
392
393
394bool Object::IsExternalUnsignedShortArray() {
395 return Object::IsHeapObject() &&
396 HeapObject::cast(this)->map()->instance_type() ==
397 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
398}
399
400
401bool Object::IsExternalIntArray() {
402 return Object::IsHeapObject() &&
403 HeapObject::cast(this)->map()->instance_type() ==
404 EXTERNAL_INT_ARRAY_TYPE;
405}
406
407
408bool Object::IsExternalUnsignedIntArray() {
409 return Object::IsHeapObject() &&
410 HeapObject::cast(this)->map()->instance_type() ==
411 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
412}
413
414
415bool Object::IsExternalFloatArray() {
416 return Object::IsHeapObject() &&
417 HeapObject::cast(this)->map()->instance_type() ==
418 EXTERNAL_FLOAT_ARRAY_TYPE;
419}
420
421
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000422bool Object::IsFailure() {
423 return HAS_FAILURE_TAG(this);
424}
425
426
427bool Object::IsRetryAfterGC() {
428 return HAS_FAILURE_TAG(this)
429 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
430}
431
432
ager@chromium.org7c537e22008-10-16 08:43:32 +0000433bool Object::IsOutOfMemoryFailure() {
434 return HAS_FAILURE_TAG(this)
435 && Failure::cast(this)->IsOutOfMemoryException();
436}
437
438
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000439bool Object::IsException() {
440 return this == Failure::Exception();
441}
442
443
444bool Object::IsJSObject() {
445 return IsHeapObject()
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000446 && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000447}
448
449
ager@chromium.org32912102009-01-16 10:38:43 +0000450bool Object::IsJSContextExtensionObject() {
451 return IsHeapObject()
452 && (HeapObject::cast(this)->map()->instance_type() ==
453 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
454}
455
456
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000457bool Object::IsMap() {
458 return Object::IsHeapObject()
459 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
460}
461
462
463bool Object::IsFixedArray() {
464 return Object::IsHeapObject()
465 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
466}
467
468
469bool Object::IsDescriptorArray() {
470 return IsFixedArray();
471}
472
473
474bool Object::IsContext() {
475 return Object::IsHeapObject()
476 && (HeapObject::cast(this)->map() == Heap::context_map() ||
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000477 HeapObject::cast(this)->map() == Heap::catch_context_map() ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000478 HeapObject::cast(this)->map() == Heap::global_context_map());
479}
480
481
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000482bool Object::IsCatchContext() {
483 return Object::IsHeapObject()
484 && HeapObject::cast(this)->map() == Heap::catch_context_map();
485}
486
487
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000488bool Object::IsGlobalContext() {
489 return Object::IsHeapObject()
490 && HeapObject::cast(this)->map() == Heap::global_context_map();
491}
492
493
494bool Object::IsJSFunction() {
495 return Object::IsHeapObject()
496 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
497}
498
499
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000500template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000501 return obj->IsJSFunction();
502}
503
504
505bool Object::IsCode() {
506 return Object::IsHeapObject()
507 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
508}
509
510
511bool Object::IsOddball() {
512 return Object::IsHeapObject()
513 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
514}
515
516
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000517bool Object::IsJSGlobalPropertyCell() {
518 return Object::IsHeapObject()
519 && HeapObject::cast(this)->map()->instance_type()
520 == JS_GLOBAL_PROPERTY_CELL_TYPE;
521}
522
523
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000524bool Object::IsSharedFunctionInfo() {
525 return Object::IsHeapObject() &&
526 (HeapObject::cast(this)->map()->instance_type() ==
527 SHARED_FUNCTION_INFO_TYPE);
528}
529
530
531bool Object::IsJSValue() {
532 return Object::IsHeapObject()
533 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
534}
535
536
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000537bool Object::IsStringWrapper() {
538 return IsJSValue() && JSValue::cast(this)->value()->IsString();
539}
540
541
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000542bool Object::IsProxy() {
543 return Object::IsHeapObject()
544 && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
545}
546
547
548bool Object::IsBoolean() {
549 return IsTrue() || IsFalse();
550}
551
552
553bool Object::IsJSArray() {
554 return Object::IsHeapObject()
555 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
556}
557
558
ager@chromium.org236ad962008-09-25 09:45:57 +0000559bool Object::IsJSRegExp() {
560 return Object::IsHeapObject()
561 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
562}
563
564
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000565template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000566 return obj->IsJSArray();
567}
568
569
570bool Object::IsHashTable() {
571 return Object::IsHeapObject()
572 && HeapObject::cast(this)->map() == Heap::hash_table_map();
573}
574
575
576bool Object::IsDictionary() {
577 return IsHashTable() && this != Heap::symbol_table();
578}
579
580
581bool Object::IsSymbolTable() {
kasperl@chromium.org68ac0092009-07-09 06:00:35 +0000582 return IsHashTable() && this == Heap::raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000583}
584
585
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000586bool Object::IsCompilationCacheTable() {
587 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000588}
589
590
ager@chromium.org236ad962008-09-25 09:45:57 +0000591bool Object::IsMapCache() {
592 return IsHashTable();
593}
594
595
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000596bool Object::IsPrimitive() {
597 return IsOddball() || IsNumber() || IsString();
598}
599
600
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000601bool Object::IsJSGlobalProxy() {
602 bool result = IsHeapObject() &&
603 (HeapObject::cast(this)->map()->instance_type() ==
604 JS_GLOBAL_PROXY_TYPE);
605 ASSERT(!result || IsAccessCheckNeeded());
606 return result;
607}
608
609
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000610bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000611 if (!IsHeapObject()) return false;
612
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000613 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000614 return type == JS_GLOBAL_OBJECT_TYPE ||
615 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000616}
617
618
619bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000620 return IsHeapObject() &&
621 (HeapObject::cast(this)->map()->instance_type() ==
622 JS_GLOBAL_OBJECT_TYPE);
623}
624
625
626bool Object::IsJSBuiltinsObject() {
627 return IsHeapObject() &&
628 (HeapObject::cast(this)->map()->instance_type() ==
629 JS_BUILTINS_OBJECT_TYPE);
630}
631
632
633bool Object::IsUndetectableObject() {
634 return IsHeapObject()
635 && HeapObject::cast(this)->map()->is_undetectable();
636}
637
638
639bool Object::IsAccessCheckNeeded() {
640 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000641 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000642}
643
644
645bool Object::IsStruct() {
646 if (!IsHeapObject()) return false;
647 switch (HeapObject::cast(this)->map()->instance_type()) {
648#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
649 STRUCT_LIST(MAKE_STRUCT_CASE)
650#undef MAKE_STRUCT_CASE
651 default: return false;
652 }
653}
654
655
656#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
657 bool Object::Is##Name() { \
658 return Object::IsHeapObject() \
659 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
660 }
661 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
662#undef MAKE_STRUCT_PREDICATE
663
664
665bool Object::IsUndefined() {
666 return this == Heap::undefined_value();
667}
668
669
670bool Object::IsTheHole() {
671 return this == Heap::the_hole_value();
672}
673
674
675bool Object::IsNull() {
676 return this == Heap::null_value();
677}
678
679
680bool Object::IsTrue() {
681 return this == Heap::true_value();
682}
683
684
685bool Object::IsFalse() {
686 return this == Heap::false_value();
687}
688
689
690double Object::Number() {
691 ASSERT(IsNumber());
692 return IsSmi()
693 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
694 : reinterpret_cast<HeapNumber*>(this)->value();
695}
696
697
698
699Object* Object::ToSmi() {
700 if (IsSmi()) return this;
701 if (IsHeapNumber()) {
702 double value = HeapNumber::cast(this)->value();
703 int int_value = FastD2I(value);
704 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
705 return Smi::FromInt(int_value);
706 }
707 }
708 return Failure::Exception();
709}
710
711
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000712bool Object::HasSpecificClassOf(String* name) {
713 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
714}
715
716
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000717Object* Object::GetElement(uint32_t index) {
718 return GetElementWithReceiver(this, index);
719}
720
721
722Object* Object::GetProperty(String* key) {
723 PropertyAttributes attributes;
724 return GetPropertyWithReceiver(this, key, &attributes);
725}
726
727
728Object* Object::GetProperty(String* key, PropertyAttributes* attributes) {
729 return GetPropertyWithReceiver(this, key, attributes);
730}
731
732
733#define FIELD_ADDR(p, offset) \
734 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
735
736#define READ_FIELD(p, offset) \
737 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
738
739#define WRITE_FIELD(p, offset, value) \
740 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
741
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000742
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000743#define WRITE_BARRIER(object, offset) \
744 Heap::RecordWrite(object->address(), offset);
745
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000746// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000747// write due to the assert validating the written value.
748#define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \
749 if (mode == UPDATE_WRITE_BARRIER) { \
750 Heap::RecordWrite(object->address(), offset); \
751 } else { \
752 ASSERT(mode == SKIP_WRITE_BARRIER); \
753 ASSERT(Heap::InNewSpace(object) || \
754 !Heap::InNewSpace(READ_FIELD(object, offset))); \
755 }
756
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000757#define READ_DOUBLE_FIELD(p, offset) \
758 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
759
760#define WRITE_DOUBLE_FIELD(p, offset, value) \
761 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
762
763#define READ_INT_FIELD(p, offset) \
764 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
765
766#define WRITE_INT_FIELD(p, offset, value) \
767 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
768
ager@chromium.org3e875802009-06-29 08:26:34 +0000769#define READ_INTPTR_FIELD(p, offset) \
770 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
771
772#define WRITE_INTPTR_FIELD(p, offset, value) \
773 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
774
ager@chromium.org7c537e22008-10-16 08:43:32 +0000775#define READ_UINT32_FIELD(p, offset) \
776 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
777
778#define WRITE_UINT32_FIELD(p, offset, value) \
779 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
780
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000781#define READ_SHORT_FIELD(p, offset) \
782 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
783
784#define WRITE_SHORT_FIELD(p, offset, value) \
785 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
786
787#define READ_BYTE_FIELD(p, offset) \
788 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
789
790#define WRITE_BYTE_FIELD(p, offset, value) \
791 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
792
793
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000794Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
795 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000796}
797
798
799int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000800 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000801}
802
803
804Smi* Smi::FromInt(int value) {
805 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000806 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000807 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000808 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000809 return reinterpret_cast<Smi*>(tagged_value);
810}
811
812
813Smi* Smi::FromIntptr(intptr_t value) {
814 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000815 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
816 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000817}
818
819
820Failure::Type Failure::type() const {
821 return static_cast<Type>(value() & kFailureTypeTagMask);
822}
823
824
825bool Failure::IsInternalError() const {
826 return type() == INTERNAL_ERROR;
827}
828
829
830bool Failure::IsOutOfMemoryException() const {
831 return type() == OUT_OF_MEMORY_EXCEPTION;
832}
833
834
835int Failure::requested() const {
836 const int kShiftBits =
837 kFailureTypeTagSize + kSpaceTagSize - kObjectAlignmentBits;
838 STATIC_ASSERT(kShiftBits >= 0);
839 ASSERT(type() == RETRY_AFTER_GC);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000840 return static_cast<int>(value() >> kShiftBits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000841}
842
843
844AllocationSpace Failure::allocation_space() const {
845 ASSERT_EQ(RETRY_AFTER_GC, type());
846 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
847 & kSpaceTagMask);
848}
849
850
851Failure* Failure::InternalError() {
852 return Construct(INTERNAL_ERROR);
853}
854
855
856Failure* Failure::Exception() {
857 return Construct(EXCEPTION);
858}
859
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000860
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000861Failure* Failure::OutOfMemoryException() {
862 return Construct(OUT_OF_MEMORY_EXCEPTION);
863}
864
865
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000866intptr_t Failure::value() const {
867 return reinterpret_cast<intptr_t>(this) >> kFailureTagSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000868}
869
870
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000871Failure* Failure::RetryAfterGC(int requested_bytes) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +0000872 // Assert that the space encoding fits in the three bytes allotted for it.
873 ASSERT((LAST_SPACE & ~kSpaceTagMask) == 0);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000874 intptr_t requested = requested_bytes >> kObjectAlignmentBits;
875 int tag_bits = kSpaceTagSize + kFailureTypeTagSize;
876 if (((requested << tag_bits) >> tag_bits) != requested) {
877 // No room for entire requested size in the bits. Round down to
878 // maximally representable size.
879 requested = static_cast<intptr_t>(
880 (~static_cast<uintptr_t>(0)) >> (tag_bits + 1));
881 }
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000882 int value = (requested << kSpaceTagSize) | NEW_SPACE;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000883 return Construct(RETRY_AFTER_GC, value);
884}
885
886
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000887Failure* Failure::Construct(Type type, intptr_t value) {
888 intptr_t info = (static_cast<intptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000889 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000890 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000891}
892
893
ager@chromium.orgab99eea2009-08-25 07:05:41 +0000894bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000895#ifdef DEBUG
896 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
897#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000898
899#ifdef V8_TARGET_ARCH_X64
900 // To be representable as a long smi, the value must be a 32-bit integer.
901 bool result = (value == static_cast<int32_t>(value));
902#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000903 // To be representable as an tagged small integer, the two
904 // most-significant bits of 'value' must be either 00 or 11 due to
905 // sign-extension. To check this we add 01 to the two
906 // most-significant bits, and check if the most-significant bit is 0
907 //
908 // CAUTION: The original code below:
909 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
910 // may lead to incorrect results according to the C language spec, and
911 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
912 // compiler may produce undefined results in case of signed integer
913 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000914 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +0000915#endif
ager@chromium.org9085a012009-05-11 19:22:57 +0000916 ASSERT(result == in_range);
917 return result;
918}
919
920
kasper.lund7276f142008-07-30 08:49:36 +0000921MapWord MapWord::FromMap(Map* map) {
922 return MapWord(reinterpret_cast<uintptr_t>(map));
923}
924
925
926Map* MapWord::ToMap() {
927 return reinterpret_cast<Map*>(value_);
928}
929
930
931bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000932 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000933}
934
935
936MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000937 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
938 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000939}
940
941
942HeapObject* MapWord::ToForwardingAddress() {
943 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000944 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000945}
946
947
ager@chromium.org3811b432009-10-28 14:53:37 +0000948bool MapWord::IsSerializationAddress() {
949 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
950}
951
952
953MapWord MapWord::FromSerializationAddress(int raw) {
954 // When the map word is being used as a serialization address we Smi-encode
955 // the serialization address (which is always a smallish positive integer).
956 return MapWord(reinterpret_cast<uintptr_t>(Smi::FromInt(raw)));
957}
958
959
960int MapWord::ToSerializationAddress() {
961 // When the map word is being used as a serialization address we treat the
962 // map word as a Smi and get the small integer that it encodes.
963 return reinterpret_cast<Smi*>(value_)->value();
964}
965
966
kasper.lund7276f142008-07-30 08:49:36 +0000967bool MapWord::IsMarked() {
968 return (value_ & kMarkingMask) == 0;
969}
970
971
972void MapWord::SetMark() {
973 value_ &= ~kMarkingMask;
974}
975
976
977void MapWord::ClearMark() {
978 value_ |= kMarkingMask;
979}
980
981
982bool MapWord::IsOverflowed() {
983 return (value_ & kOverflowMask) != 0;
984}
985
986
987void MapWord::SetOverflow() {
988 value_ |= kOverflowMask;
989}
990
991
992void MapWord::ClearOverflow() {
993 value_ &= ~kOverflowMask;
994}
995
996
997MapWord MapWord::EncodeAddress(Address map_address, int offset) {
998 // Offset is the distance in live bytes from the first live object in the
999 // same page. The offset between two objects in the same page should not
1000 // exceed the object area size of a page.
1001 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
1002
1003 int compact_offset = offset >> kObjectAlignmentBits;
1004 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
1005
1006 Page* map_page = Page::FromAddress(map_address);
1007 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1008
1009 int map_page_offset =
1010 map_page->Offset(map_address) >> kObjectAlignmentBits;
1011
1012 uintptr_t encoding =
1013 (compact_offset << kForwardingOffsetShift) |
1014 (map_page_offset << kMapPageOffsetShift) |
1015 (map_page->mc_page_index << kMapPageIndexShift);
1016 return MapWord(encoding);
1017}
1018
1019
1020Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001021 int map_page_index =
1022 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001023 ASSERT_MAP_PAGE_INDEX(map_page_index);
1024
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001025 int map_page_offset = static_cast<int>(
kasper.lund7276f142008-07-30 08:49:36 +00001026 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift)
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001027 << kObjectAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001028
1029 return (map_space->PageAddress(map_page_index) + map_page_offset);
1030}
1031
1032
1033int MapWord::DecodeOffset() {
1034 // The offset field is represented in the kForwardingOffsetBits
1035 // most-significant bits.
1036 int offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1037 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
1038 return offset;
1039}
1040
1041
1042MapWord MapWord::FromEncodedAddress(Address address) {
1043 return MapWord(reinterpret_cast<uintptr_t>(address));
1044}
1045
1046
1047Address MapWord::ToEncodedAddress() {
1048 return reinterpret_cast<Address>(value_);
1049}
1050
1051
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001052#ifdef DEBUG
1053void HeapObject::VerifyObjectField(int offset) {
1054 VerifyPointer(READ_FIELD(this, offset));
1055}
1056#endif
1057
1058
1059Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001060 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001061}
1062
1063
1064void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001065 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001066}
1067
1068
kasper.lund7276f142008-07-30 08:49:36 +00001069MapWord HeapObject::map_word() {
1070 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1071}
1072
1073
1074void HeapObject::set_map_word(MapWord map_word) {
1075 // WRITE_FIELD does not update the remembered set, but there is no need
1076 // here.
1077 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1078}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001079
1080
1081HeapObject* HeapObject::FromAddress(Address address) {
1082 ASSERT_TAG_ALIGNED(address);
1083 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1084}
1085
1086
1087Address HeapObject::address() {
1088 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1089}
1090
1091
1092int HeapObject::Size() {
1093 return SizeFromMap(map());
1094}
1095
1096
1097void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1098 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1099 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1100}
1101
1102
1103void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1104 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1105}
1106
1107
kasper.lund7276f142008-07-30 08:49:36 +00001108bool HeapObject::IsMarked() {
1109 return map_word().IsMarked();
1110}
1111
1112
1113void HeapObject::SetMark() {
1114 ASSERT(!IsMarked());
1115 MapWord first_word = map_word();
1116 first_word.SetMark();
1117 set_map_word(first_word);
1118}
1119
1120
1121void HeapObject::ClearMark() {
1122 ASSERT(IsMarked());
1123 MapWord first_word = map_word();
1124 first_word.ClearMark();
1125 set_map_word(first_word);
1126}
1127
1128
1129bool HeapObject::IsOverflowed() {
1130 return map_word().IsOverflowed();
1131}
1132
1133
1134void HeapObject::SetOverflow() {
1135 MapWord first_word = map_word();
1136 first_word.SetOverflow();
1137 set_map_word(first_word);
1138}
1139
1140
1141void HeapObject::ClearOverflow() {
1142 ASSERT(IsOverflowed());
1143 MapWord first_word = map_word();
1144 first_word.ClearOverflow();
1145 set_map_word(first_word);
1146}
1147
1148
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001149double HeapNumber::value() {
1150 return READ_DOUBLE_FIELD(this, kValueOffset);
1151}
1152
1153
1154void HeapNumber::set_value(double value) {
1155 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1156}
1157
1158
1159ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001160
1161
1162Array* JSObject::elements() {
1163 Object* array = READ_FIELD(this, kElementsOffset);
1164 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001165 ASSERT(array->IsFixedArray() || array->IsPixelArray() ||
1166 array->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001167 return reinterpret_cast<Array*>(array);
1168}
1169
1170
1171void JSObject::set_elements(Array* value, WriteBarrierMode mode) {
1172 // In the assert below Dictionary is covered under FixedArray.
ager@chromium.org3811b432009-10-28 14:53:37 +00001173 ASSERT(value->IsFixedArray() || value->IsPixelArray() ||
1174 value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001175 WRITE_FIELD(this, kElementsOffset, value);
1176 CONDITIONAL_WRITE_BARRIER(this, kElementsOffset, mode);
1177}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001178
1179
1180void JSObject::initialize_properties() {
1181 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1182 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1183}
1184
1185
1186void JSObject::initialize_elements() {
1187 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1188 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1189}
1190
1191
1192ACCESSORS(Oddball, to_string, String, kToStringOffset)
1193ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1194
1195
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001196Object* JSGlobalPropertyCell::value() {
1197 return READ_FIELD(this, kValueOffset);
1198}
1199
1200
1201void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1202 // The write barrier is not used for global property cells.
1203 ASSERT(!val->IsJSGlobalPropertyCell());
1204 WRITE_FIELD(this, kValueOffset, val);
1205}
1206
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001207
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001208int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001209 InstanceType type = map()->instance_type();
1210 // Check for the most common kind of JavaScript object before
1211 // falling into the generic switch. This speeds up the internal
1212 // field operations considerably on average.
1213 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1214 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001215 case JS_GLOBAL_PROXY_TYPE:
1216 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001217 case JS_GLOBAL_OBJECT_TYPE:
1218 return JSGlobalObject::kSize;
1219 case JS_BUILTINS_OBJECT_TYPE:
1220 return JSBuiltinsObject::kSize;
1221 case JS_FUNCTION_TYPE:
1222 return JSFunction::kSize;
1223 case JS_VALUE_TYPE:
1224 return JSValue::kSize;
1225 case JS_ARRAY_TYPE:
1226 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001227 case JS_REGEXP_TYPE:
1228 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001229 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001230 return JSObject::kHeaderSize;
1231 default:
1232 UNREACHABLE();
1233 return 0;
1234 }
1235}
1236
1237
1238int JSObject::GetInternalFieldCount() {
1239 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001240 // Make sure to adjust for the number of in-object properties. These
1241 // properties do contribute to the size, but are not internal fields.
1242 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1243 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001244}
1245
1246
1247Object* JSObject::GetInternalField(int index) {
1248 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001249 // Internal objects do follow immediately after the header, whereas in-object
1250 // properties are at the end of the object. Therefore there is no need
1251 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001252 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1253}
1254
1255
1256void JSObject::SetInternalField(int index, Object* value) {
1257 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001258 // Internal objects do follow immediately after the header, whereas in-object
1259 // properties are at the end of the object. Therefore there is no need
1260 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001261 int offset = GetHeaderSize() + (kPointerSize * index);
1262 WRITE_FIELD(this, offset, value);
1263 WRITE_BARRIER(this, offset);
1264}
1265
1266
ager@chromium.org7c537e22008-10-16 08:43:32 +00001267// Access fast-case object properties at index. The use of these routines
1268// is needed to correctly distinguish between properties stored in-object and
1269// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001270Object* JSObject::FastPropertyAt(int index) {
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 return READ_FIELD(this, offset);
1276 } else {
1277 ASSERT(index < properties()->length());
1278 return properties()->get(index);
1279 }
1280}
1281
1282
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001283Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001284 // Adjust for the number of properties stored in the object.
1285 index -= map()->inobject_properties();
1286 if (index < 0) {
1287 int offset = map()->instance_size() + (index * kPointerSize);
1288 WRITE_FIELD(this, offset, value);
1289 WRITE_BARRIER(this, offset);
1290 } else {
1291 ASSERT(index < properties()->length());
1292 properties()->set(index, value);
1293 }
1294 return value;
1295}
1296
1297
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001298Object* JSObject::InObjectPropertyAt(int index) {
1299 // Adjust for the number of properties stored in the object.
1300 index -= map()->inobject_properties();
1301 ASSERT(index < 0);
1302 int offset = map()->instance_size() + (index * kPointerSize);
1303 return READ_FIELD(this, offset);
1304}
1305
1306
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001307Object* JSObject::InObjectPropertyAtPut(int index,
1308 Object* value,
1309 WriteBarrierMode mode) {
1310 // Adjust for the number of properties stored in the object.
1311 index -= map()->inobject_properties();
1312 ASSERT(index < 0);
1313 int offset = map()->instance_size() + (index * kPointerSize);
1314 WRITE_FIELD(this, offset, value);
1315 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1316 return value;
1317}
1318
1319
1320
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001321void JSObject::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001322 Object* value = Heap::undefined_value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001323 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001324 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001325 }
1326}
1327
1328
1329void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001330 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001331 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001332 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001333 }
1334}
1335
1336
1337bool JSObject::HasFastProperties() {
1338 return !properties()->IsDictionary();
1339}
1340
1341
1342bool Array::IndexFromObject(Object* object, uint32_t* index) {
1343 if (object->IsSmi()) {
1344 int value = Smi::cast(object)->value();
1345 if (value < 0) return false;
1346 *index = value;
1347 return true;
1348 }
1349 if (object->IsHeapNumber()) {
1350 double value = HeapNumber::cast(object)->value();
1351 uint32_t uint_value = static_cast<uint32_t>(value);
1352 if (value == static_cast<double>(uint_value)) {
1353 *index = uint_value;
1354 return true;
1355 }
1356 }
1357 return false;
1358}
1359
1360
1361bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1362 if (!this->IsJSValue()) return false;
1363
1364 JSValue* js_value = JSValue::cast(this);
1365 if (!js_value->value()->IsString()) return false;
1366
1367 String* str = String::cast(js_value->value());
1368 if (index >= (uint32_t)str->length()) return false;
1369
1370 return true;
1371}
1372
1373
1374Object* FixedArray::get(int index) {
1375 ASSERT(index >= 0 && index < this->length());
1376 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1377}
1378
1379
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001380void FixedArray::set(int index, Smi* value) {
1381 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1382 int offset = kHeaderSize + index * kPointerSize;
1383 WRITE_FIELD(this, offset, value);
1384}
1385
1386
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001387void FixedArray::set(int index, Object* value) {
1388 ASSERT(index >= 0 && index < this->length());
1389 int offset = kHeaderSize + index * kPointerSize;
1390 WRITE_FIELD(this, offset, value);
1391 WRITE_BARRIER(this, offset);
1392}
1393
1394
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001395WriteBarrierMode HeapObject::GetWriteBarrierMode() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001396 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1397 return UPDATE_WRITE_BARRIER;
1398}
1399
1400
1401void FixedArray::set(int index,
1402 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001403 WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001404 ASSERT(index >= 0 && index < this->length());
1405 int offset = kHeaderSize + index * kPointerSize;
1406 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001407 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001408}
1409
1410
1411void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
1412 ASSERT(index >= 0 && index < array->length());
1413 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1414}
1415
1416
1417void FixedArray::set_undefined(int index) {
1418 ASSERT(index >= 0 && index < this->length());
1419 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1420 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1421 Heap::undefined_value());
1422}
1423
1424
ager@chromium.org236ad962008-09-25 09:45:57 +00001425void FixedArray::set_null(int index) {
1426 ASSERT(index >= 0 && index < this->length());
1427 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1428 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1429}
1430
1431
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001432void FixedArray::set_the_hole(int index) {
1433 ASSERT(index >= 0 && index < this->length());
1434 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1435 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1436}
1437
1438
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001439bool DescriptorArray::IsEmpty() {
1440 ASSERT(this == Heap::empty_descriptor_array() ||
1441 this->length() > 2);
1442 return this == Heap::empty_descriptor_array();
1443}
1444
1445
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001446void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1447 Object* tmp = array->get(first);
1448 fast_set(array, first, array->get(second));
1449 fast_set(array, second, tmp);
1450}
1451
1452
1453int DescriptorArray::Search(String* name) {
1454 SLOW_ASSERT(IsSortedNoDuplicates());
1455
1456 // Check for empty descriptor array.
1457 int nof = number_of_descriptors();
1458 if (nof == 0) return kNotFound;
1459
1460 // Fast case: do linear search for small arrays.
1461 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001462 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001463 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001464 }
1465
1466 // Slow case: perform binary search.
1467 return BinarySearch(name, 0, nof - 1);
1468}
1469
1470
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001471String* DescriptorArray::GetKey(int descriptor_number) {
1472 ASSERT(descriptor_number < number_of_descriptors());
1473 return String::cast(get(ToKeyIndex(descriptor_number)));
1474}
1475
1476
1477Object* DescriptorArray::GetValue(int descriptor_number) {
1478 ASSERT(descriptor_number < number_of_descriptors());
1479 return GetContentArray()->get(ToValueIndex(descriptor_number));
1480}
1481
1482
1483Smi* DescriptorArray::GetDetails(int descriptor_number) {
1484 ASSERT(descriptor_number < number_of_descriptors());
1485 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1486}
1487
1488
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001489PropertyType DescriptorArray::GetType(int descriptor_number) {
1490 ASSERT(descriptor_number < number_of_descriptors());
1491 return PropertyDetails(GetDetails(descriptor_number)).type();
1492}
1493
1494
1495int DescriptorArray::GetFieldIndex(int descriptor_number) {
1496 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1497}
1498
1499
1500JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1501 return JSFunction::cast(GetValue(descriptor_number));
1502}
1503
1504
1505Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1506 ASSERT(GetType(descriptor_number) == CALLBACKS);
1507 return GetValue(descriptor_number);
1508}
1509
1510
1511AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1512 ASSERT(GetType(descriptor_number) == CALLBACKS);
1513 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1514 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1515}
1516
1517
1518bool DescriptorArray::IsProperty(int descriptor_number) {
1519 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1520}
1521
1522
1523bool DescriptorArray::IsTransition(int descriptor_number) {
1524 PropertyType t = GetType(descriptor_number);
1525 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION;
1526}
1527
1528
1529bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1530 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1531}
1532
1533
1534bool DescriptorArray::IsDontEnum(int descriptor_number) {
1535 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1536}
1537
1538
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001539void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1540 desc->Init(GetKey(descriptor_number),
1541 GetValue(descriptor_number),
1542 GetDetails(descriptor_number));
1543}
1544
1545
1546void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1547 // Range check.
1548 ASSERT(descriptor_number < number_of_descriptors());
1549
1550 // Make sure non of the elements in desc are in new space.
1551 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1552 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1553
1554 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1555 FixedArray* content_array = GetContentArray();
1556 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1557 fast_set(content_array, ToDetailsIndex(descriptor_number),
1558 desc->GetDetails().AsSmi());
1559}
1560
1561
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001562void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1563 Descriptor desc;
1564 src->Get(src_index, &desc);
1565 Set(index, &desc);
1566}
1567
1568
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001569void DescriptorArray::Swap(int first, int second) {
1570 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1571 FixedArray* content_array = GetContentArray();
1572 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1573 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1574}
1575
1576
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001577bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001578 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001579 if (!max_index_object->IsSmi()) return false;
1580 return 0 !=
1581 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1582}
1583
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001584uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001585 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001586 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001587 if (!max_index_object->IsSmi()) return 0;
1588 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1589 return value >> kRequiresSlowElementsTagSize;
1590}
1591
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001592void NumberDictionary::set_requires_slow_elements() {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001593 set(kMaxNumberKeyIndex,
1594 Smi::FromInt(kRequiresSlowElementsMask),
1595 SKIP_WRITE_BARRIER);
1596}
1597
1598
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001599// ------------------------------------
1600// Cast operations
1601
1602
1603CAST_ACCESSOR(FixedArray)
1604CAST_ACCESSOR(DescriptorArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001605CAST_ACCESSOR(SymbolTable)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001606CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001607CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001608CAST_ACCESSOR(String)
1609CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001610CAST_ACCESSOR(SeqAsciiString)
1611CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001612CAST_ACCESSOR(ConsString)
1613CAST_ACCESSOR(SlicedString)
1614CAST_ACCESSOR(ExternalString)
1615CAST_ACCESSOR(ExternalAsciiString)
1616CAST_ACCESSOR(ExternalTwoByteString)
1617CAST_ACCESSOR(JSObject)
1618CAST_ACCESSOR(Smi)
1619CAST_ACCESSOR(Failure)
1620CAST_ACCESSOR(HeapObject)
1621CAST_ACCESSOR(HeapNumber)
1622CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001623CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001624CAST_ACCESSOR(SharedFunctionInfo)
1625CAST_ACCESSOR(Map)
1626CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001627CAST_ACCESSOR(GlobalObject)
1628CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001629CAST_ACCESSOR(JSGlobalObject)
1630CAST_ACCESSOR(JSBuiltinsObject)
1631CAST_ACCESSOR(Code)
1632CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001633CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001634CAST_ACCESSOR(Proxy)
1635CAST_ACCESSOR(ByteArray)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001636CAST_ACCESSOR(PixelArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001637CAST_ACCESSOR(ExternalArray)
1638CAST_ACCESSOR(ExternalByteArray)
1639CAST_ACCESSOR(ExternalUnsignedByteArray)
1640CAST_ACCESSOR(ExternalShortArray)
1641CAST_ACCESSOR(ExternalUnsignedShortArray)
1642CAST_ACCESSOR(ExternalIntArray)
1643CAST_ACCESSOR(ExternalUnsignedIntArray)
1644CAST_ACCESSOR(ExternalFloatArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001645CAST_ACCESSOR(Struct)
1646
1647
1648#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1649 STRUCT_LIST(MAKE_STRUCT_CAST)
1650#undef MAKE_STRUCT_CAST
1651
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001652
1653template <typename Shape, typename Key>
1654HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001655 ASSERT(obj->IsHashTable());
1656 return reinterpret_cast<HashTable*>(obj);
1657}
1658
1659
1660INT_ACCESSORS(Array, length, kLengthOffset)
1661
1662
1663bool String::Equals(String* other) {
1664 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001665 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1666 return false;
1667 }
1668 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001669}
1670
1671
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001672int String::length() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001673 uint32_t len = READ_INT_FIELD(this, kLengthOffset);
1674
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001675 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift);
1676 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift);
1677 ASSERT(kLongStringTag == 0);
1678
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001679 return len >> (StringShape(this).size_tag() + kLongLengthShift);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001680}
1681
1682
1683void String::set_length(int value) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001684 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift);
1685 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift);
1686 ASSERT(kLongStringTag == 0);
1687
1688 WRITE_INT_FIELD(this,
1689 kLengthOffset,
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001690 value << (StringShape(this).size_tag() + kLongLengthShift));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001691}
1692
1693
ager@chromium.org7c537e22008-10-16 08:43:32 +00001694uint32_t String::length_field() {
1695 return READ_UINT32_FIELD(this, kLengthOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001696}
1697
1698
ager@chromium.org7c537e22008-10-16 08:43:32 +00001699void String::set_length_field(uint32_t value) {
1700 WRITE_UINT32_FIELD(this, kLengthOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001701}
1702
1703
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001704Object* String::TryFlattenIfNotFlat() {
ager@chromium.org236ad962008-09-25 09:45:57 +00001705 // We don't need to flatten strings that are already flat. Since this code
1706 // is inlined, it can be helpful in the flat case to not call out to Flatten.
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001707 if (!IsFlat()) {
1708 return TryFlatten();
ager@chromium.org236ad962008-09-25 09:45:57 +00001709 }
ager@chromium.orgddb913d2009-01-27 10:01:48 +00001710 return this;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001711}
1712
1713
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001714uint16_t String::Get(int index) {
1715 ASSERT(index >= 0 && index < length());
1716 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001717 case kSeqStringTag | kAsciiStringTag:
1718 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1719 case kSeqStringTag | kTwoByteStringTag:
1720 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1721 case kConsStringTag | kAsciiStringTag:
1722 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001723 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001724 case kSlicedStringTag | kAsciiStringTag:
1725 case kSlicedStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001726 return SlicedString::cast(this)->SlicedStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001727 case kExternalStringTag | kAsciiStringTag:
1728 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1729 case kExternalStringTag | kTwoByteStringTag:
1730 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001731 default:
1732 break;
1733 }
1734
1735 UNREACHABLE();
1736 return 0;
1737}
1738
1739
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001740void String::Set(int index, uint16_t value) {
1741 ASSERT(index >= 0 && index < length());
1742 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001743
ager@chromium.org5ec48922009-05-05 07:25:34 +00001744 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001745 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1746 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001747}
1748
1749
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001750bool String::IsFlat() {
1751 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001752 case kConsStringTag: {
1753 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001754 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001755 return second->length() == 0;
1756 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001757 case kSlicedStringTag: {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001758 StringRepresentationTag tag =
1759 StringShape(SlicedString::cast(this)->buffer()).representation_tag();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001760 return tag == kSeqStringTag || tag == kExternalStringTag;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001761 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001762 default:
1763 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001764 }
1765}
1766
1767
ager@chromium.org7c537e22008-10-16 08:43:32 +00001768uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001769 ASSERT(index >= 0 && index < length());
1770 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1771}
1772
1773
ager@chromium.org7c537e22008-10-16 08:43:32 +00001774void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001775 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1776 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1777 static_cast<byte>(value));
1778}
1779
1780
ager@chromium.org7c537e22008-10-16 08:43:32 +00001781Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001782 return FIELD_ADDR(this, kHeaderSize);
1783}
1784
1785
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001786char* SeqAsciiString::GetChars() {
1787 return reinterpret_cast<char*>(GetCharsAddress());
1788}
1789
1790
ager@chromium.org7c537e22008-10-16 08:43:32 +00001791Address SeqTwoByteString::GetCharsAddress() {
1792 return FIELD_ADDR(this, kHeaderSize);
1793}
1794
1795
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001796uc16* SeqTwoByteString::GetChars() {
1797 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1798}
1799
1800
ager@chromium.org7c537e22008-10-16 08:43:32 +00001801uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001802 ASSERT(index >= 0 && index < length());
1803 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1804}
1805
1806
ager@chromium.org7c537e22008-10-16 08:43:32 +00001807void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001808 ASSERT(index >= 0 && index < length());
1809 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1810}
1811
1812
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001813int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001814 uint32_t length = READ_INT_FIELD(this, kLengthOffset);
1815
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001816 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift);
1817 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift);
1818 ASSERT(kLongStringTag == 0);
1819
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001820 // Use the map (and not 'this') to compute the size tag, since
1821 // TwoByteStringSize is called during GC when maps are encoded.
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001822 length >>= StringShape(instance_type).size_tag() + kLongLengthShift;
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001823
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001824 return SizeFor(length);
1825}
1826
1827
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001828int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001829 uint32_t length = READ_INT_FIELD(this, kLengthOffset);
1830
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001831 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift);
1832 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift);
1833 ASSERT(kLongStringTag == 0);
1834
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001835 // Use the map (and not 'this') to compute the size tag, since
1836 // AsciiStringSize is called during GC when maps are encoded.
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001837 length >>= StringShape(instance_type).size_tag() + kLongLengthShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001838
1839 return SizeFor(length);
1840}
1841
1842
ager@chromium.org870a0b62008-11-04 11:43:05 +00001843String* ConsString::first() {
1844 return String::cast(READ_FIELD(this, kFirstOffset));
1845}
1846
1847
1848Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001849 return READ_FIELD(this, kFirstOffset);
1850}
1851
1852
ager@chromium.org870a0b62008-11-04 11:43:05 +00001853void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001854 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001855 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001856}
1857
1858
ager@chromium.org870a0b62008-11-04 11:43:05 +00001859String* ConsString::second() {
1860 return String::cast(READ_FIELD(this, kSecondOffset));
1861}
1862
1863
1864Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001865 return READ_FIELD(this, kSecondOffset);
1866}
1867
1868
ager@chromium.org870a0b62008-11-04 11:43:05 +00001869void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001870 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001871 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001872}
1873
1874
ager@chromium.org870a0b62008-11-04 11:43:05 +00001875String* SlicedString::buffer() {
1876 return String::cast(READ_FIELD(this, kBufferOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001877}
1878
1879
ager@chromium.org870a0b62008-11-04 11:43:05 +00001880void SlicedString::set_buffer(String* buffer) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001881 WRITE_FIELD(this, kBufferOffset, buffer);
1882 WRITE_BARRIER(this, kBufferOffset);
1883}
1884
1885
1886int SlicedString::start() {
1887 return READ_INT_FIELD(this, kStartOffset);
1888}
1889
1890
1891void SlicedString::set_start(int start) {
1892 WRITE_INT_FIELD(this, kStartOffset, start);
1893}
1894
1895
1896ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1897 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1898}
1899
1900
1901void ExternalAsciiString::set_resource(
1902 ExternalAsciiString::Resource* resource) {
1903 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1904}
1905
1906
ager@chromium.org6f10e412009-02-13 10:11:16 +00001907Map* ExternalAsciiString::StringMap(int length) {
1908 Map* map;
1909 // Number of characters: determines the map.
ager@chromium.org3811b432009-10-28 14:53:37 +00001910 if (length <= String::kMaxShortSize) {
ager@chromium.org6f10e412009-02-13 10:11:16 +00001911 map = Heap::short_external_ascii_string_map();
ager@chromium.org3811b432009-10-28 14:53:37 +00001912 } else if (length <= String::kMaxMediumSize) {
ager@chromium.org6f10e412009-02-13 10:11:16 +00001913 map = Heap::medium_external_ascii_string_map();
1914 } else {
1915 map = Heap::long_external_ascii_string_map();
1916 }
1917 return map;
1918}
1919
1920
1921Map* ExternalAsciiString::SymbolMap(int length) {
1922 Map* map;
1923 // Number of characters: determines the map.
ager@chromium.org3811b432009-10-28 14:53:37 +00001924 if (length <= String::kMaxShortSize) {
ager@chromium.org6f10e412009-02-13 10:11:16 +00001925 map = Heap::short_external_ascii_symbol_map();
ager@chromium.org3811b432009-10-28 14:53:37 +00001926 } else if (length <= String::kMaxMediumSize) {
ager@chromium.org6f10e412009-02-13 10:11:16 +00001927 map = Heap::medium_external_ascii_symbol_map();
1928 } else {
1929 map = Heap::long_external_ascii_symbol_map();
1930 }
1931 return map;
1932}
1933
1934
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001935ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1936 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1937}
1938
1939
1940void ExternalTwoByteString::set_resource(
1941 ExternalTwoByteString::Resource* resource) {
1942 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1943}
1944
1945
ager@chromium.org6f10e412009-02-13 10:11:16 +00001946Map* ExternalTwoByteString::StringMap(int length) {
1947 Map* map;
1948 // Number of characters: determines the map.
ager@chromium.org3811b432009-10-28 14:53:37 +00001949 if (length <= String::kMaxShortSize) {
ager@chromium.org6f10e412009-02-13 10:11:16 +00001950 map = Heap::short_external_string_map();
ager@chromium.org3811b432009-10-28 14:53:37 +00001951 } else if (length <= String::kMaxMediumSize) {
ager@chromium.org6f10e412009-02-13 10:11:16 +00001952 map = Heap::medium_external_string_map();
1953 } else {
1954 map = Heap::long_external_string_map();
1955 }
1956 return map;
1957}
1958
1959
1960Map* ExternalTwoByteString::SymbolMap(int length) {
1961 Map* map;
1962 // Number of characters: determines the map.
ager@chromium.org3811b432009-10-28 14:53:37 +00001963 if (length <= String::kMaxShortSize) {
ager@chromium.org6f10e412009-02-13 10:11:16 +00001964 map = Heap::short_external_symbol_map();
ager@chromium.org3811b432009-10-28 14:53:37 +00001965 } else if (length <= String::kMaxMediumSize) {
ager@chromium.org6f10e412009-02-13 10:11:16 +00001966 map = Heap::medium_external_symbol_map();
1967 } else {
1968 map = Heap::long_external_symbol_map();
1969 }
1970 return map;
1971}
1972
1973
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001974byte ByteArray::get(int index) {
1975 ASSERT(index >= 0 && index < this->length());
1976 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1977}
1978
1979
1980void ByteArray::set(int index, byte value) {
1981 ASSERT(index >= 0 && index < this->length());
1982 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
1983}
1984
1985
1986int ByteArray::get_int(int index) {
1987 ASSERT(index >= 0 && (index * kIntSize) < this->length());
1988 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
1989}
1990
1991
1992ByteArray* ByteArray::FromDataStartAddress(Address address) {
1993 ASSERT_TAG_ALIGNED(address);
1994 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
1995}
1996
1997
1998Address ByteArray::GetDataStartAddress() {
1999 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2000}
2001
2002
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002003uint8_t* PixelArray::external_pointer() {
2004 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2005 return reinterpret_cast<uint8_t*>(ptr);
2006}
2007
2008
2009void PixelArray::set_external_pointer(uint8_t* value, WriteBarrierMode mode) {
2010 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2011 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2012}
2013
2014
2015uint8_t PixelArray::get(int index) {
2016 ASSERT((index >= 0) && (index < this->length()));
2017 uint8_t* ptr = external_pointer();
2018 return ptr[index];
2019}
2020
2021
2022void PixelArray::set(int index, uint8_t value) {
2023 ASSERT((index >= 0) && (index < this->length()));
2024 uint8_t* ptr = external_pointer();
2025 ptr[index] = value;
2026}
2027
2028
ager@chromium.org3811b432009-10-28 14:53:37 +00002029void* ExternalArray::external_pointer() {
2030 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2031 return reinterpret_cast<void*>(ptr);
2032}
2033
2034
2035void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2036 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2037 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2038}
2039
2040
2041int8_t ExternalByteArray::get(int index) {
2042 ASSERT((index >= 0) && (index < this->length()));
2043 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2044 return ptr[index];
2045}
2046
2047
2048void ExternalByteArray::set(int index, int8_t value) {
2049 ASSERT((index >= 0) && (index < this->length()));
2050 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2051 ptr[index] = value;
2052}
2053
2054
2055uint8_t ExternalUnsignedByteArray::get(int index) {
2056 ASSERT((index >= 0) && (index < this->length()));
2057 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2058 return ptr[index];
2059}
2060
2061
2062void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2063 ASSERT((index >= 0) && (index < this->length()));
2064 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2065 ptr[index] = value;
2066}
2067
2068
2069int16_t ExternalShortArray::get(int index) {
2070 ASSERT((index >= 0) && (index < this->length()));
2071 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2072 return ptr[index];
2073}
2074
2075
2076void ExternalShortArray::set(int index, int16_t value) {
2077 ASSERT((index >= 0) && (index < this->length()));
2078 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2079 ptr[index] = value;
2080}
2081
2082
2083uint16_t ExternalUnsignedShortArray::get(int index) {
2084 ASSERT((index >= 0) && (index < this->length()));
2085 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2086 return ptr[index];
2087}
2088
2089
2090void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2091 ASSERT((index >= 0) && (index < this->length()));
2092 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2093 ptr[index] = value;
2094}
2095
2096
2097int32_t ExternalIntArray::get(int index) {
2098 ASSERT((index >= 0) && (index < this->length()));
2099 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2100 return ptr[index];
2101}
2102
2103
2104void ExternalIntArray::set(int index, int32_t value) {
2105 ASSERT((index >= 0) && (index < this->length()));
2106 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2107 ptr[index] = value;
2108}
2109
2110
2111uint32_t ExternalUnsignedIntArray::get(int index) {
2112 ASSERT((index >= 0) && (index < this->length()));
2113 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2114 return ptr[index];
2115}
2116
2117
2118void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2119 ASSERT((index >= 0) && (index < this->length()));
2120 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2121 ptr[index] = value;
2122}
2123
2124
2125float ExternalFloatArray::get(int index) {
2126 ASSERT((index >= 0) && (index < this->length()));
2127 float* ptr = static_cast<float*>(external_pointer());
2128 return ptr[index];
2129}
2130
2131
2132void ExternalFloatArray::set(int index, float value) {
2133 ASSERT((index >= 0) && (index < this->length()));
2134 float* ptr = static_cast<float*>(external_pointer());
2135 ptr[index] = value;
2136}
2137
2138
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002139int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002140 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2141}
2142
2143
2144int Map::inobject_properties() {
2145 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002146}
2147
2148
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002149int Map::pre_allocated_property_fields() {
2150 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2151}
2152
2153
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002154int HeapObject::SizeFromMap(Map* map) {
2155 InstanceType instance_type = map->instance_type();
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002156 // Only inline the most frequent cases.
2157 if (instance_type == JS_OBJECT_TYPE ||
2158 (instance_type & (kIsNotStringMask | kStringRepresentationMask)) ==
2159 (kStringTag | kConsStringTag) ||
2160 instance_type == JS_ARRAY_TYPE) return map->instance_size();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002161 if (instance_type == FIXED_ARRAY_TYPE) {
2162 return reinterpret_cast<FixedArray*>(this)->FixedArraySize();
2163 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002164 if (instance_type == BYTE_ARRAY_TYPE) {
2165 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2166 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002167 // Otherwise do the general size computation.
2168 return SlowSizeFromMap(map);
2169}
2170
2171
2172void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002173 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002174 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002175 ASSERT(0 <= value && value < 256);
2176 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2177}
2178
2179
ager@chromium.org7c537e22008-10-16 08:43:32 +00002180void Map::set_inobject_properties(int value) {
2181 ASSERT(0 <= value && value < 256);
2182 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2183}
2184
2185
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002186void Map::set_pre_allocated_property_fields(int value) {
2187 ASSERT(0 <= value && value < 256);
2188 WRITE_BYTE_FIELD(this,
2189 kPreAllocatedPropertyFieldsOffset,
2190 static_cast<byte>(value));
2191}
2192
2193
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002194InstanceType Map::instance_type() {
2195 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2196}
2197
2198
2199void Map::set_instance_type(InstanceType value) {
2200 ASSERT(0 <= value && value < 256);
2201 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2202}
2203
2204
2205int Map::unused_property_fields() {
2206 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2207}
2208
2209
2210void Map::set_unused_property_fields(int value) {
2211 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2212}
2213
2214
2215byte Map::bit_field() {
2216 return READ_BYTE_FIELD(this, kBitFieldOffset);
2217}
2218
2219
2220void Map::set_bit_field(byte value) {
2221 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2222}
2223
2224
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002225byte Map::bit_field2() {
2226 return READ_BYTE_FIELD(this, kBitField2Offset);
2227}
2228
2229
2230void Map::set_bit_field2(byte value) {
2231 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2232}
2233
2234
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002235void Map::set_non_instance_prototype(bool value) {
2236 if (value) {
2237 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2238 } else {
2239 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2240 }
2241}
2242
2243
2244bool Map::has_non_instance_prototype() {
2245 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2246}
2247
2248
ager@chromium.org870a0b62008-11-04 11:43:05 +00002249void Map::set_is_access_check_needed(bool access_check_needed) {
2250 if (access_check_needed) {
2251 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2252 } else {
2253 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2254 }
2255}
2256
2257
2258bool Map::is_access_check_needed() {
2259 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2260}
2261
2262
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002263Code::Flags Code::flags() {
2264 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2265}
2266
2267
2268void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002269 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002270 // Make sure that all call stubs have an arguments count.
2271 ASSERT(ExtractKindFromFlags(flags) != CALL_IC ||
2272 ExtractArgumentsCountFromFlags(flags) >= 0);
2273 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2274}
2275
2276
2277Code::Kind Code::kind() {
2278 return ExtractKindFromFlags(flags());
2279}
2280
2281
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002282InLoopFlag Code::ic_in_loop() {
2283 return ExtractICInLoopFromFlags(flags());
2284}
2285
2286
kasper.lund7276f142008-07-30 08:49:36 +00002287InlineCacheState Code::ic_state() {
2288 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002289 // Only allow uninitialized or debugger states for non-IC code
2290 // objects. This is used in the debugger to determine whether or not
2291 // a call to code object has been replaced with a debug break call.
2292 ASSERT(is_inline_cache_stub() ||
2293 result == UNINITIALIZED ||
2294 result == DEBUG_BREAK ||
2295 result == DEBUG_PREPARE_STEP_IN);
2296 return result;
2297}
2298
2299
2300PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002301 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002302 return ExtractTypeFromFlags(flags());
2303}
2304
2305
2306int Code::arguments_count() {
2307 ASSERT(is_call_stub() || kind() == STUB);
2308 return ExtractArgumentsCountFromFlags(flags());
2309}
2310
2311
2312CodeStub::Major Code::major_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002313 ASSERT(kind() == STUB);
kasper.lund7276f142008-07-30 08:49:36 +00002314 return static_cast<CodeStub::Major>(READ_BYTE_FIELD(this,
2315 kStubMajorKeyOffset));
2316}
2317
2318
2319void Code::set_major_key(CodeStub::Major major) {
2320 ASSERT(kind() == STUB);
2321 ASSERT(0 <= major && major < 256);
2322 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002323}
2324
2325
2326bool Code::is_inline_cache_stub() {
2327 Kind kind = this->kind();
2328 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2329}
2330
2331
2332Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002333 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002334 InlineCacheState ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002335 PropertyType type,
2336 int argc) {
2337 // Compute the bit mask.
2338 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002339 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002340 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002341 bits |= type << kFlagsTypeShift;
2342 bits |= argc << kFlagsArgumentsCountShift;
2343 // Cast to flags and validate result before returning it.
2344 Flags result = static_cast<Flags>(bits);
2345 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002346 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002347 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002348 ASSERT(ExtractTypeFromFlags(result) == type);
2349 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2350 return result;
2351}
2352
2353
2354Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2355 PropertyType type,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002356 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002357 int argc) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002358 return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002359}
2360
2361
2362Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2363 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2364 return static_cast<Kind>(bits);
2365}
2366
2367
kasper.lund7276f142008-07-30 08:49:36 +00002368InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2369 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002370 return static_cast<InlineCacheState>(bits);
2371}
2372
2373
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002374InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2375 int bits = (flags & kFlagsICInLoopMask);
2376 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2377}
2378
2379
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002380PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2381 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2382 return static_cast<PropertyType>(bits);
2383}
2384
2385
2386int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2387 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2388}
2389
2390
2391Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2392 int bits = flags & ~kFlagsTypeMask;
2393 return static_cast<Flags>(bits);
2394}
2395
2396
ager@chromium.org8bb60582008-12-11 12:02:20 +00002397Code* Code::GetCodeFromTargetAddress(Address address) {
2398 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2399 // GetCodeFromTargetAddress might be called when marking objects during mark
2400 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2401 // Code::cast. Code::cast does not work when the object's map is
2402 // marked.
2403 Code* result = reinterpret_cast<Code*>(code);
2404 return result;
2405}
2406
2407
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002408Object* Map::prototype() {
2409 return READ_FIELD(this, kPrototypeOffset);
2410}
2411
2412
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002413void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002414 ASSERT(value->IsNull() || value->IsJSObject());
2415 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002416 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002417}
2418
2419
2420ACCESSORS(Map, instance_descriptors, DescriptorArray,
2421 kInstanceDescriptorsOffset)
2422ACCESSORS(Map, code_cache, FixedArray, kCodeCacheOffset)
2423ACCESSORS(Map, constructor, Object, kConstructorOffset)
2424
2425ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2426ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
2427
2428ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2429ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002430ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002431
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002432ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002433
2434ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2435ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2436ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2437ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2438ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
ager@chromium.org3811b432009-10-28 14:53:37 +00002439ACCESSORS(AccessorInfo, load_stub_cache, Object, kLoadStubCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002440
2441ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2442ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2443ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2444
2445ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2446ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2447ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2448ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2449ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2450ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2451
2452ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2453ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2454
2455ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2456ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2457
2458ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2459ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002460ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2461 kPropertyAccessorsOffset)
2462ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2463 kPrototypeTemplateOffset)
2464ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2465ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2466 kNamedPropertyHandlerOffset)
2467ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2468 kIndexedPropertyHandlerOffset)
2469ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2470 kInstanceTemplateOffset)
2471ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2472ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002473ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2474 kInstanceCallHandlerOffset)
2475ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2476 kAccessCheckInfoOffset)
2477ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2478
2479ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002480ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2481 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002482
2483ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2484ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2485
2486ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2487
2488ACCESSORS(Script, source, Object, kSourceOffset)
2489ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002490ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002491ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2492ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002493ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002494ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002495ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2496ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002497ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
iposva@chromium.org245aa852009-02-10 00:49:54 +00002498ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002499ACCESSORS(Script, eval_from_function, Object, kEvalFromFunctionOffset)
2500ACCESSORS(Script, eval_from_instructions_offset, Smi,
2501 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002502
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002503#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002504ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2505ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2506ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2507ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2508
2509ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2510ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2511ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2512ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002513#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002514
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002515ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002516ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
2517ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2518 kInstanceClassNameOffset)
2519ACCESSORS(SharedFunctionInfo, function_data, Object,
2520 kExternalReferenceDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002521ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2522ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002523ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002524ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
2525 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002526
2527BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2528 kHiddenPrototypeBit)
2529BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2530BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2531 kNeedsAccessCheckBit)
2532BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2533 kIsExpressionBit)
2534BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2535 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002536BOOL_GETTER(SharedFunctionInfo, compiler_hints,
2537 has_only_this_property_assignments,
2538 kHasOnlyThisPropertyAssignments)
2539BOOL_GETTER(SharedFunctionInfo, compiler_hints,
2540 has_only_simple_this_property_assignments,
2541 kHasOnlySimpleThisPropertyAssignments)
2542
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002543
2544INT_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2545INT_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
2546 kFormalParameterCountOffset)
2547INT_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
2548 kExpectedNofPropertiesOffset)
2549INT_ACCESSORS(SharedFunctionInfo, start_position_and_type,
2550 kStartPositionAndTypeOffset)
2551INT_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2552INT_ACCESSORS(SharedFunctionInfo, function_token_position,
2553 kFunctionTokenPositionOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002554INT_ACCESSORS(SharedFunctionInfo, compiler_hints,
2555 kCompilerHintsOffset)
2556INT_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
2557 kThisPropertyAssignmentsCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002558
2559
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00002560bool Script::HasValidSource() {
2561 Object* src = this->source();
2562 if (!src->IsString()) return true;
2563 String* src_str = String::cast(src);
2564 if (!StringShape(src_str).IsExternal()) return true;
2565 if (src_str->IsAsciiRepresentation()) {
2566 return ExternalAsciiString::cast(src)->resource() != NULL;
2567 } else if (src_str->IsTwoByteRepresentation()) {
2568 return ExternalTwoByteString::cast(src)->resource() != NULL;
2569 }
2570 return true;
2571}
2572
2573
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002574void SharedFunctionInfo::DontAdaptArguments() {
2575 ASSERT(code()->kind() == Code::BUILTIN);
2576 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2577}
2578
2579
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002580int SharedFunctionInfo::start_position() {
2581 return start_position_and_type() >> kStartPositionShift;
2582}
2583
2584
2585void SharedFunctionInfo::set_start_position(int start_position) {
2586 set_start_position_and_type((start_position << kStartPositionShift)
2587 | (start_position_and_type() & ~kStartPositionMask));
2588}
2589
2590
2591Code* SharedFunctionInfo::code() {
2592 return Code::cast(READ_FIELD(this, kCodeOffset));
2593}
2594
2595
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002596void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002597 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002598 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002599}
2600
2601
2602bool SharedFunctionInfo::is_compiled() {
2603 // TODO(1242782): Create a code kind for uncompiled code.
2604 return code()->kind() != Code::STUB;
2605}
2606
2607
2608bool JSFunction::IsBoilerplate() {
2609 return map() == Heap::boilerplate_function_map();
2610}
2611
2612
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002613bool JSFunction::IsBuiltin() {
2614 return context()->global()->IsJSBuiltinsObject();
2615}
2616
2617
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002618bool JSObject::IsLoaded() {
2619 return !map()->needs_loading();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002620}
2621
2622
2623Code* JSFunction::code() {
2624 return shared()->code();
2625}
2626
2627
2628void JSFunction::set_code(Code* value) {
2629 shared()->set_code(value);
2630}
2631
2632
2633Context* JSFunction::context() {
2634 return Context::cast(READ_FIELD(this, kContextOffset));
2635}
2636
2637
2638Object* JSFunction::unchecked_context() {
2639 return READ_FIELD(this, kContextOffset);
2640}
2641
2642
2643void JSFunction::set_context(Object* value) {
2644 ASSERT(value == Heap::undefined_value() || value->IsContext());
2645 WRITE_FIELD(this, kContextOffset, value);
2646 WRITE_BARRIER(this, kContextOffset);
2647}
2648
2649ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2650 kPrototypeOrInitialMapOffset)
2651
2652
2653Map* JSFunction::initial_map() {
2654 return Map::cast(prototype_or_initial_map());
2655}
2656
2657
2658void JSFunction::set_initial_map(Map* value) {
2659 set_prototype_or_initial_map(value);
2660}
2661
2662
2663bool JSFunction::has_initial_map() {
2664 return prototype_or_initial_map()->IsMap();
2665}
2666
2667
2668bool JSFunction::has_instance_prototype() {
2669 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2670}
2671
2672
2673bool JSFunction::has_prototype() {
2674 return map()->has_non_instance_prototype() || has_instance_prototype();
2675}
2676
2677
2678Object* JSFunction::instance_prototype() {
2679 ASSERT(has_instance_prototype());
2680 if (has_initial_map()) return initial_map()->prototype();
2681 // When there is no initial map and the prototype is a JSObject, the
2682 // initial map field is used for the prototype field.
2683 return prototype_or_initial_map();
2684}
2685
2686
2687Object* JSFunction::prototype() {
2688 ASSERT(has_prototype());
2689 // If the function's prototype property has been set to a non-JSObject
2690 // value, that value is stored in the constructor field of the map.
2691 if (map()->has_non_instance_prototype()) return map()->constructor();
2692 return instance_prototype();
2693}
2694
2695
2696bool JSFunction::is_compiled() {
2697 return shared()->is_compiled();
2698}
2699
2700
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002701int JSFunction::NumberOfLiterals() {
2702 return literals()->length();
2703}
2704
2705
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002706Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2707 ASSERT(0 <= id && id < kJSBuiltinsCount);
2708 return READ_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize));
2709}
2710
2711
2712void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2713 Object* value) {
2714 ASSERT(0 <= id && id < kJSBuiltinsCount);
2715 WRITE_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize), value);
2716 WRITE_BARRIER(this, kJSBuiltinsOffset + (id * kPointerSize));
2717}
2718
2719
2720Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00002721 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002722}
2723
2724
2725void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002726 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002727}
2728
2729
2730void Proxy::ProxyIterateBody(ObjectVisitor* visitor) {
2731 visitor->VisitExternalReference(
2732 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
2733}
2734
2735
2736ACCESSORS(JSValue, value, Object, kValueOffset)
2737
2738
2739JSValue* JSValue::cast(Object* obj) {
2740 ASSERT(obj->IsJSValue());
2741 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2742 return reinterpret_cast<JSValue*>(obj);
2743}
2744
2745
2746INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
2747INT_ACCESSORS(Code, relocation_size, kRelocationSizeOffset)
2748INT_ACCESSORS(Code, sinfo_size, kSInfoSizeOffset)
2749
2750
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002751byte* Code::instruction_start() {
2752 return FIELD_ADDR(this, kHeaderSize);
2753}
2754
2755
2756int Code::body_size() {
2757 return RoundUp(instruction_size() + relocation_size(), kObjectAlignment);
2758}
2759
2760
2761byte* Code::relocation_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002762 return FIELD_ADDR(this, kHeaderSize + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002763}
2764
2765
2766byte* Code::entry() {
2767 return instruction_start();
2768}
2769
2770
2771bool Code::contains(byte* pc) {
2772 return (instruction_start() <= pc) &&
2773 (pc < instruction_start() + instruction_size());
2774}
2775
2776
2777byte* Code::sinfo_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002778 return FIELD_ADDR(this, kHeaderSize + body_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002779}
2780
2781
2782ACCESSORS(JSArray, length, Object, kLengthOffset)
2783
2784
ager@chromium.org236ad962008-09-25 09:45:57 +00002785ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00002786
2787
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002788JSRegExp::Type JSRegExp::TypeTag() {
2789 Object* data = this->data();
2790 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
2791 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
2792 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00002793}
2794
2795
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002796int JSRegExp::CaptureCount() {
2797 switch (TypeTag()) {
2798 case ATOM:
2799 return 0;
2800 case IRREGEXP:
2801 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
2802 default:
2803 UNREACHABLE();
2804 return -1;
2805 }
2806}
2807
2808
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002809JSRegExp::Flags JSRegExp::GetFlags() {
2810 ASSERT(this->data()->IsFixedArray());
2811 Object* data = this->data();
2812 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
2813 return Flags(smi->value());
2814}
2815
2816
2817String* JSRegExp::Pattern() {
2818 ASSERT(this->data()->IsFixedArray());
2819 Object* data = this->data();
2820 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
2821 return pattern;
2822}
2823
2824
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002825Object* JSRegExp::DataAt(int index) {
2826 ASSERT(TypeTag() != NOT_COMPILED);
2827 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00002828}
2829
2830
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002831void JSRegExp::SetDataAt(int index, Object* value) {
2832 ASSERT(TypeTag() != NOT_COMPILED);
2833 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
2834 FixedArray::cast(data())->set(index, value);
2835}
2836
2837
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002838JSObject::ElementsKind JSObject::GetElementsKind() {
2839 Array* array = elements();
2840 if (array->IsFixedArray()) {
2841 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a FixedArray.
2842 if (array->map() == Heap::fixed_array_map()) {
2843 return FAST_ELEMENTS;
2844 }
2845 ASSERT(array->IsDictionary());
2846 return DICTIONARY_ELEMENTS;
2847 }
ager@chromium.org3811b432009-10-28 14:53:37 +00002848 if (array->IsExternalArray()) {
2849 switch (array->map()->instance_type()) {
2850 case EXTERNAL_BYTE_ARRAY_TYPE:
2851 return EXTERNAL_BYTE_ELEMENTS;
2852 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
2853 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2854 case EXTERNAL_SHORT_ARRAY_TYPE:
2855 return EXTERNAL_SHORT_ELEMENTS;
2856 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
2857 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2858 case EXTERNAL_INT_ARRAY_TYPE:
2859 return EXTERNAL_INT_ELEMENTS;
2860 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
2861 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
2862 default:
2863 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
2864 return EXTERNAL_FLOAT_ELEMENTS;
2865 }
2866 }
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002867 ASSERT(array->IsPixelArray());
2868 return PIXEL_ELEMENTS;
2869}
2870
2871
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002872bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002873 return GetElementsKind() == FAST_ELEMENTS;
2874}
2875
2876
2877bool JSObject::HasDictionaryElements() {
2878 return GetElementsKind() == DICTIONARY_ELEMENTS;
2879}
2880
2881
2882bool JSObject::HasPixelElements() {
2883 return GetElementsKind() == PIXEL_ELEMENTS;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002884}
2885
2886
ager@chromium.org3811b432009-10-28 14:53:37 +00002887bool JSObject::HasExternalArrayElements() {
2888 return (HasExternalByteElements() ||
2889 HasExternalUnsignedByteElements() ||
2890 HasExternalShortElements() ||
2891 HasExternalUnsignedShortElements() ||
2892 HasExternalIntElements() ||
2893 HasExternalUnsignedIntElements() ||
2894 HasExternalFloatElements());
2895}
2896
2897
2898bool JSObject::HasExternalByteElements() {
2899 return GetElementsKind() == EXTERNAL_BYTE_ELEMENTS;
2900}
2901
2902
2903bool JSObject::HasExternalUnsignedByteElements() {
2904 return GetElementsKind() == EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
2905}
2906
2907
2908bool JSObject::HasExternalShortElements() {
2909 return GetElementsKind() == EXTERNAL_SHORT_ELEMENTS;
2910}
2911
2912
2913bool JSObject::HasExternalUnsignedShortElements() {
2914 return GetElementsKind() == EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
2915}
2916
2917
2918bool JSObject::HasExternalIntElements() {
2919 return GetElementsKind() == EXTERNAL_INT_ELEMENTS;
2920}
2921
2922
2923bool JSObject::HasExternalUnsignedIntElements() {
2924 return GetElementsKind() == EXTERNAL_UNSIGNED_INT_ELEMENTS;
2925}
2926
2927
2928bool JSObject::HasExternalFloatElements() {
2929 return GetElementsKind() == EXTERNAL_FLOAT_ELEMENTS;
2930}
2931
2932
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002933bool JSObject::HasNamedInterceptor() {
2934 return map()->has_named_interceptor();
2935}
2936
2937
2938bool JSObject::HasIndexedInterceptor() {
2939 return map()->has_indexed_interceptor();
2940}
2941
2942
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002943StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002944 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002945 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002946}
2947
2948
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002949NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002950 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002951 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002952}
2953
2954
2955bool String::HasHashCode() {
2956 return (length_field() & kHashComputedMask) != 0;
2957}
2958
2959
2960uint32_t String::Hash() {
2961 // Fast case: has hash code already been computed?
ager@chromium.org7c537e22008-10-16 08:43:32 +00002962 uint32_t field = length_field();
2963 if (field & kHashComputedMask) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002964 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002965 return ComputeAndSetHash();
2966}
2967
2968
ager@chromium.org7c537e22008-10-16 08:43:32 +00002969StringHasher::StringHasher(int length)
2970 : length_(length),
2971 raw_running_hash_(0),
2972 array_index_(0),
2973 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
2974 is_first_char_(true),
2975 is_valid_(true) { }
2976
2977
2978bool StringHasher::has_trivial_hash() {
ager@chromium.org3811b432009-10-28 14:53:37 +00002979 return length_ > String::kMaxMediumSize;
ager@chromium.org7c537e22008-10-16 08:43:32 +00002980}
2981
2982
2983void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002984 // Use the Jenkins one-at-a-time hash function to update the hash
2985 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002986 raw_running_hash_ += c;
2987 raw_running_hash_ += (raw_running_hash_ << 10);
2988 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002989 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002990 if (is_array_index_) {
2991 if (c < '0' || c > '9') {
2992 is_array_index_ = false;
2993 } else {
2994 int d = c - '0';
2995 if (is_first_char_) {
2996 is_first_char_ = false;
2997 if (c == '0' && length_ > 1) {
2998 is_array_index_ = false;
2999 return;
3000 }
3001 }
3002 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3003 is_array_index_ = false;
3004 } else {
3005 array_index_ = array_index_ * 10 + d;
3006 }
3007 }
3008 }
3009}
3010
3011
3012void StringHasher::AddCharacterNoIndex(uc32 c) {
3013 ASSERT(!is_array_index());
3014 raw_running_hash_ += c;
3015 raw_running_hash_ += (raw_running_hash_ << 10);
3016 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3017}
3018
3019
3020uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003021 // Get the calculated raw hash value and do some more bit ops to distribute
3022 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003023 uint32_t result = raw_running_hash_;
3024 result += (result << 3);
3025 result ^= (result >> 11);
3026 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003027 if (result == 0) {
3028 result = 27;
3029 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003030 return result;
3031}
3032
3033
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003034bool String::AsArrayIndex(uint32_t* index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00003035 uint32_t field = length_field();
3036 if ((field & kHashComputedMask) && !(field & kIsArrayIndexMask)) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003037 return SlowAsArrayIndex(index);
3038}
3039
3040
3041Object* JSObject::GetPrototype() {
3042 return JSObject::cast(this)->map()->prototype();
3043}
3044
3045
3046PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
3047 return GetPropertyAttributeWithReceiver(this, key);
3048}
3049
3050
3051bool JSObject::HasElement(uint32_t index) {
3052 return HasElementWithReceiver(this, index);
3053}
3054
3055
3056bool AccessorInfo::all_can_read() {
3057 return BooleanBit::get(flag(), kAllCanReadBit);
3058}
3059
3060
3061void AccessorInfo::set_all_can_read(bool value) {
3062 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3063}
3064
3065
3066bool AccessorInfo::all_can_write() {
3067 return BooleanBit::get(flag(), kAllCanWriteBit);
3068}
3069
3070
3071void AccessorInfo::set_all_can_write(bool value) {
3072 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3073}
3074
3075
ager@chromium.org870a0b62008-11-04 11:43:05 +00003076bool AccessorInfo::prohibits_overwriting() {
3077 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3078}
3079
3080
3081void AccessorInfo::set_prohibits_overwriting(bool value) {
3082 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3083}
3084
3085
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003086PropertyAttributes AccessorInfo::property_attributes() {
3087 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3088}
3089
3090
3091void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3092 ASSERT(AttributesField::is_valid(attributes));
3093 int rest_value = flag()->value() & ~AttributesField::mask();
3094 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3095}
3096
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003097template<typename Shape, typename Key>
3098void Dictionary<Shape, Key>::SetEntry(int entry,
3099 Object* key,
3100 Object* value,
3101 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003102 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003103 int index = HashTable<Shape, Key>::EntryToIndex(entry);
3104 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode();
3105 FixedArray::set(index, key, mode);
3106 FixedArray::set(index+1, value, mode);
3107 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003108}
3109
3110
3111void Map::ClearCodeCache() {
3112 // No write barrier is needed since empty_fixed_array is not in new space.
3113 // Please note this function is used during marking:
3114 // - MarkCompactCollector::MarkUnmarkedObject
kasperl@chromium.org68ac0092009-07-09 06:00:35 +00003115 ASSERT(!Heap::InNewSpace(Heap::raw_unchecked_empty_fixed_array()));
3116 WRITE_FIELD(this, kCodeCacheOffset, Heap::raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003117}
3118
3119
ager@chromium.org5aa501c2009-06-23 07:57:28 +00003120void JSArray::EnsureSize(int required_size) {
3121 ASSERT(HasFastElements());
3122 if (elements()->length() >= required_size) return;
3123 Expand(required_size);
3124}
3125
3126
ager@chromium.org7c537e22008-10-16 08:43:32 +00003127void JSArray::SetContent(FixedArray* storage) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003128 set_length(Smi::FromInt(storage->length()), SKIP_WRITE_BARRIER);
ager@chromium.org7c537e22008-10-16 08:43:32 +00003129 set_elements(storage);
3130}
3131
3132
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003133Object* FixedArray::Copy() {
3134 if (length() == 0) return this;
3135 return Heap::CopyFixedArray(this);
3136}
3137
3138
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003139#undef CAST_ACCESSOR
3140#undef INT_ACCESSORS
3141#undef SMI_ACCESSORS
3142#undef ACCESSORS
3143#undef FIELD_ADDR
3144#undef READ_FIELD
3145#undef WRITE_FIELD
3146#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003147#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003148#undef READ_MEMADDR_FIELD
3149#undef WRITE_MEMADDR_FIELD
3150#undef READ_DOUBLE_FIELD
3151#undef WRITE_DOUBLE_FIELD
3152#undef READ_INT_FIELD
3153#undef WRITE_INT_FIELD
3154#undef READ_SHORT_FIELD
3155#undef WRITE_SHORT_FIELD
3156#undef READ_BYTE_FIELD
3157#undef WRITE_BYTE_FIELD
3158
3159
3160} } // namespace v8::internal
3161
3162#endif // V8_OBJECTS_INL_H_