blob: 8c83715649b56b796c0732521397935b8ca5b59a [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
56#define CAST_ACCESSOR(type) \
57 type* type::cast(Object* object) { \
58 ASSERT(object->Is##type()); \
59 return reinterpret_cast<type*>(object); \
60 }
61
62
63#define INT_ACCESSORS(holder, name, offset) \
64 int holder::name() { return READ_INT_FIELD(this, offset); } \
65 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
66
67
68#define ACCESSORS(holder, name, type, offset) \
69 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000070 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000071 WRITE_FIELD(this, offset, value); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000072 CONDITIONAL_WRITE_BARRIER(this, offset, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000073 }
74
75
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000076
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000077#define SMI_ACCESSORS(holder, name, offset) \
78 int holder::name() { \
79 Object* value = READ_FIELD(this, offset); \
80 return Smi::cast(value)->value(); \
81 } \
82 void holder::set_##name(int value) { \
83 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
84 }
85
86
87#define BOOL_ACCESSORS(holder, field, name, offset) \
88 bool holder::name() { \
89 return BooleanBit::get(field(), offset); \
90 } \
91 void holder::set_##name(bool value) { \
92 set_##field(BooleanBit::set(field(), offset, value)); \
93 }
94
95
96bool Object::IsSmi() {
97 return HAS_SMI_TAG(this);
98}
99
100
101bool Object::IsHeapObject() {
102 return HAS_HEAP_OBJECT_TAG(this);
103}
104
105
106bool Object::IsHeapNumber() {
107 return Object::IsHeapObject()
108 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE;
109}
110
111
112bool Object::IsString() {
113 return Object::IsHeapObject()
114 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
115}
116
117
ager@chromium.org870a0b62008-11-04 11:43:05 +0000118bool Object::IsSymbol() {
119 if (!this->IsHeapObject()) return false;
120 uint32_t type = HeapObject::cast(this)->map()->instance_type();
121 return (type & (kIsNotStringMask | kIsSymbolMask)) ==
122 (kStringTag | kSymbolTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000123}
124
125
126bool Object::IsConsString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000127 if (!this->IsHeapObject()) return false;
128 uint32_t type = HeapObject::cast(this)->map()->instance_type();
129 return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
130 (kStringTag | kConsStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000131}
132
133
ager@chromium.org870a0b62008-11-04 11:43:05 +0000134#ifdef DEBUG
135// These are for cast checks. If you need one of these in release
136// mode you should consider using a StringShape before moving it out
137// of the ifdef
138
139bool Object::IsSeqString() {
140 if (!IsString()) return false;
141 return StringShape(String::cast(this)).IsSequential();
142}
143
144
145bool Object::IsSeqAsciiString() {
146 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000147 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000148 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000149}
150
151
152bool Object::IsSeqTwoByteString() {
153 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000154 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000155 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000156}
157
158
159bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000160 if (!IsString()) return false;
161 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000162}
163
164
165bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000166 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000167 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000168 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000169}
170
171
172bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000173 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000174 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000175 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000176}
177
178
ager@chromium.org870a0b62008-11-04 11:43:05 +0000179bool Object::IsSlicedString() {
180 if (!IsString()) return false;
181 return StringShape(String::cast(this)).IsSliced();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000182}
183
184
ager@chromium.org870a0b62008-11-04 11:43:05 +0000185#endif // DEBUG
186
187
188StringShape::StringShape(String* str)
189 : type_(str->map()->instance_type()) {
190 set_valid();
191 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000192}
193
194
ager@chromium.org870a0b62008-11-04 11:43:05 +0000195StringShape::StringShape(Map* map)
196 : type_(map->instance_type()) {
197 set_valid();
198 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000199}
200
201
ager@chromium.org870a0b62008-11-04 11:43:05 +0000202StringShape::StringShape(InstanceType t)
203 : type_(static_cast<uint32_t>(t)) {
204 set_valid();
205 ASSERT((type_ & kIsNotStringMask) == kStringTag);
206}
207
208
209bool StringShape::IsSymbol() {
210 ASSERT(valid());
211 return (type_ & kIsSymbolMask) == kSymbolTag;
212}
213
214
ager@chromium.org5ec48922009-05-05 07:25:34 +0000215bool String::IsAsciiRepresentation() {
216 uint32_t type = map()->instance_type();
217 if ((type & kStringRepresentationMask) == kSlicedStringTag) {
218 return SlicedString::cast(this)->buffer()->IsAsciiRepresentation();
219 }
220 if ((type & kStringRepresentationMask) == kConsStringTag &&
221 ConsString::cast(this)->second()->length() == 0) {
222 return ConsString::cast(this)->first()->IsAsciiRepresentation();
223 }
224 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000225}
226
227
ager@chromium.org5ec48922009-05-05 07:25:34 +0000228bool String::IsTwoByteRepresentation() {
229 uint32_t type = map()->instance_type();
230 if ((type & kStringRepresentationMask) == kSlicedStringTag) {
231 return SlicedString::cast(this)->buffer()->IsTwoByteRepresentation();
232 } else if ((type & kStringRepresentationMask) == kConsStringTag &&
233 ConsString::cast(this)->second()->length() == 0) {
234 return ConsString::cast(this)->first()->IsTwoByteRepresentation();
235 }
236 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000237}
238
239
240bool StringShape::IsCons() {
241 return (type_ & kStringRepresentationMask) == kConsStringTag;
242}
243
244
245bool StringShape::IsSliced() {
246 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
247}
248
249
250bool StringShape::IsExternal() {
251 return (type_ & kStringRepresentationMask) == kExternalStringTag;
252}
253
254
255bool StringShape::IsSequential() {
256 return (type_ & kStringRepresentationMask) == kSeqStringTag;
257}
258
259
260StringRepresentationTag StringShape::representation_tag() {
261 uint32_t tag = (type_ & kStringRepresentationMask);
262 return static_cast<StringRepresentationTag>(tag);
263}
264
265
266uint32_t StringShape::full_representation_tag() {
267 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
268}
269
270
271uint32_t StringShape::size_tag() {
272 return (type_ & kStringSizeMask);
273}
274
275
276bool StringShape::IsSequentialAscii() {
277 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
278}
279
280
281bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000282 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000283}
284
285
286bool StringShape::IsExternalAscii() {
287 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
288}
289
290
291bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000292 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000293}
294
295
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000296uc32 FlatStringReader::Get(int index) {
297 ASSERT(0 <= index && index <= length_);
298 if (is_ascii_) {
299 return static_cast<const byte*>(start_)[index];
300 } else {
301 return static_cast<const uc16*>(start_)[index];
302 }
303}
304
305
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000306bool Object::IsNumber() {
307 return IsSmi() || IsHeapNumber();
308}
309
310
311bool Object::IsByteArray() {
312 return Object::IsHeapObject()
313 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
314}
315
316
317bool Object::IsFailure() {
318 return HAS_FAILURE_TAG(this);
319}
320
321
322bool Object::IsRetryAfterGC() {
323 return HAS_FAILURE_TAG(this)
324 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
325}
326
327
ager@chromium.org7c537e22008-10-16 08:43:32 +0000328bool Object::IsOutOfMemoryFailure() {
329 return HAS_FAILURE_TAG(this)
330 && Failure::cast(this)->IsOutOfMemoryException();
331}
332
333
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000334bool Object::IsException() {
335 return this == Failure::Exception();
336}
337
338
339bool Object::IsJSObject() {
340 return IsHeapObject()
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000341 && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000342}
343
344
ager@chromium.org32912102009-01-16 10:38:43 +0000345bool Object::IsJSContextExtensionObject() {
346 return IsHeapObject()
347 && (HeapObject::cast(this)->map()->instance_type() ==
348 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
349}
350
351
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000352bool Object::IsMap() {
353 return Object::IsHeapObject()
354 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
355}
356
357
358bool Object::IsFixedArray() {
359 return Object::IsHeapObject()
360 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
361}
362
363
364bool Object::IsDescriptorArray() {
365 return IsFixedArray();
366}
367
368
369bool Object::IsContext() {
370 return Object::IsHeapObject()
371 && (HeapObject::cast(this)->map() == Heap::context_map() ||
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000372 HeapObject::cast(this)->map() == Heap::catch_context_map() ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000373 HeapObject::cast(this)->map() == Heap::global_context_map());
374}
375
376
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000377bool Object::IsCatchContext() {
378 return Object::IsHeapObject()
379 && HeapObject::cast(this)->map() == Heap::catch_context_map();
380}
381
382
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000383bool Object::IsGlobalContext() {
384 return Object::IsHeapObject()
385 && HeapObject::cast(this)->map() == Heap::global_context_map();
386}
387
388
389bool Object::IsJSFunction() {
390 return Object::IsHeapObject()
391 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
392}
393
394
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000395template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000396 return obj->IsJSFunction();
397}
398
399
400bool Object::IsCode() {
401 return Object::IsHeapObject()
402 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
403}
404
405
406bool Object::IsOddball() {
407 return Object::IsHeapObject()
408 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
409}
410
411
412bool Object::IsSharedFunctionInfo() {
413 return Object::IsHeapObject() &&
414 (HeapObject::cast(this)->map()->instance_type() ==
415 SHARED_FUNCTION_INFO_TYPE);
416}
417
418
419bool Object::IsJSValue() {
420 return Object::IsHeapObject()
421 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
422}
423
424
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000425bool Object::IsStringWrapper() {
426 return IsJSValue() && JSValue::cast(this)->value()->IsString();
427}
428
429
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000430bool Object::IsProxy() {
431 return Object::IsHeapObject()
432 && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
433}
434
435
436bool Object::IsBoolean() {
437 return IsTrue() || IsFalse();
438}
439
440
441bool Object::IsJSArray() {
442 return Object::IsHeapObject()
443 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
444}
445
446
ager@chromium.org236ad962008-09-25 09:45:57 +0000447bool Object::IsJSRegExp() {
448 return Object::IsHeapObject()
449 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
450}
451
452
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000453template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000454 return obj->IsJSArray();
455}
456
457
458bool Object::IsHashTable() {
459 return Object::IsHeapObject()
460 && HeapObject::cast(this)->map() == Heap::hash_table_map();
461}
462
463
464bool Object::IsDictionary() {
465 return IsHashTable() && this != Heap::symbol_table();
466}
467
468
469bool Object::IsSymbolTable() {
470 return IsHashTable() && this == Heap::symbol_table();
471}
472
473
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000474bool Object::IsCompilationCacheTable() {
475 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000476}
477
478
ager@chromium.org236ad962008-09-25 09:45:57 +0000479bool Object::IsMapCache() {
480 return IsHashTable();
481}
482
483
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000484bool Object::IsPrimitive() {
485 return IsOddball() || IsNumber() || IsString();
486}
487
488
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000489bool Object::IsJSGlobalProxy() {
490 bool result = IsHeapObject() &&
491 (HeapObject::cast(this)->map()->instance_type() ==
492 JS_GLOBAL_PROXY_TYPE);
493 ASSERT(!result || IsAccessCheckNeeded());
494 return result;
495}
496
497
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000498bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000499 if (!IsHeapObject()) return false;
500
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000501 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000502 return type == JS_GLOBAL_OBJECT_TYPE ||
503 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000504}
505
506
507bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000508 return IsHeapObject() &&
509 (HeapObject::cast(this)->map()->instance_type() ==
510 JS_GLOBAL_OBJECT_TYPE);
511}
512
513
514bool Object::IsJSBuiltinsObject() {
515 return IsHeapObject() &&
516 (HeapObject::cast(this)->map()->instance_type() ==
517 JS_BUILTINS_OBJECT_TYPE);
518}
519
520
521bool Object::IsUndetectableObject() {
522 return IsHeapObject()
523 && HeapObject::cast(this)->map()->is_undetectable();
524}
525
526
527bool Object::IsAccessCheckNeeded() {
528 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000529 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000530}
531
532
533bool Object::IsStruct() {
534 if (!IsHeapObject()) return false;
535 switch (HeapObject::cast(this)->map()->instance_type()) {
536#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
537 STRUCT_LIST(MAKE_STRUCT_CASE)
538#undef MAKE_STRUCT_CASE
539 default: return false;
540 }
541}
542
543
544#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
545 bool Object::Is##Name() { \
546 return Object::IsHeapObject() \
547 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
548 }
549 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
550#undef MAKE_STRUCT_PREDICATE
551
552
553bool Object::IsUndefined() {
554 return this == Heap::undefined_value();
555}
556
557
558bool Object::IsTheHole() {
559 return this == Heap::the_hole_value();
560}
561
562
563bool Object::IsNull() {
564 return this == Heap::null_value();
565}
566
567
568bool Object::IsTrue() {
569 return this == Heap::true_value();
570}
571
572
573bool Object::IsFalse() {
574 return this == Heap::false_value();
575}
576
577
578double Object::Number() {
579 ASSERT(IsNumber());
580 return IsSmi()
581 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
582 : reinterpret_cast<HeapNumber*>(this)->value();
583}
584
585
586
587Object* Object::ToSmi() {
588 if (IsSmi()) return this;
589 if (IsHeapNumber()) {
590 double value = HeapNumber::cast(this)->value();
591 int int_value = FastD2I(value);
592 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
593 return Smi::FromInt(int_value);
594 }
595 }
596 return Failure::Exception();
597}
598
599
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000600bool Object::HasSpecificClassOf(String* name) {
601 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
602}
603
604
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000605Object* Object::GetElement(uint32_t index) {
606 return GetElementWithReceiver(this, index);
607}
608
609
610Object* Object::GetProperty(String* key) {
611 PropertyAttributes attributes;
612 return GetPropertyWithReceiver(this, key, &attributes);
613}
614
615
616Object* Object::GetProperty(String* key, PropertyAttributes* attributes) {
617 return GetPropertyWithReceiver(this, key, attributes);
618}
619
620
621#define FIELD_ADDR(p, offset) \
622 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
623
624#define READ_FIELD(p, offset) \
625 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
626
627#define WRITE_FIELD(p, offset, value) \
628 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
629
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000630
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000631#define WRITE_BARRIER(object, offset) \
632 Heap::RecordWrite(object->address(), offset);
633
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000634// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000635// write due to the assert validating the written value.
636#define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \
637 if (mode == UPDATE_WRITE_BARRIER) { \
638 Heap::RecordWrite(object->address(), offset); \
639 } else { \
640 ASSERT(mode == SKIP_WRITE_BARRIER); \
641 ASSERT(Heap::InNewSpace(object) || \
642 !Heap::InNewSpace(READ_FIELD(object, offset))); \
643 }
644
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000645#define READ_DOUBLE_FIELD(p, offset) \
646 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
647
648#define WRITE_DOUBLE_FIELD(p, offset, value) \
649 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
650
651#define READ_INT_FIELD(p, offset) \
652 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
653
654#define WRITE_INT_FIELD(p, offset, value) \
655 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
656
ager@chromium.org3e875802009-06-29 08:26:34 +0000657#define READ_INTPTR_FIELD(p, offset) \
658 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
659
660#define WRITE_INTPTR_FIELD(p, offset, value) \
661 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
662
ager@chromium.org7c537e22008-10-16 08:43:32 +0000663#define READ_UINT32_FIELD(p, offset) \
664 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
665
666#define WRITE_UINT32_FIELD(p, offset, value) \
667 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
668
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000669#define READ_SHORT_FIELD(p, offset) \
670 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
671
672#define WRITE_SHORT_FIELD(p, offset, value) \
673 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
674
675#define READ_BYTE_FIELD(p, offset) \
676 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
677
678#define WRITE_BYTE_FIELD(p, offset, value) \
679 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
680
681
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000682Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
683 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000684}
685
686
687int Smi::value() {
ager@chromium.org5ec48922009-05-05 07:25:34 +0000688 return static_cast<int>(reinterpret_cast<intptr_t>(this) >> kSmiTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000689}
690
691
692Smi* Smi::FromInt(int value) {
693 ASSERT(Smi::IsValid(value));
ager@chromium.org9085a012009-05-11 19:22:57 +0000694 intptr_t tagged_value =
695 (static_cast<intptr_t>(value) << kSmiTagSize) | kSmiTag;
696 return reinterpret_cast<Smi*>(tagged_value);
697}
698
699
700Smi* Smi::FromIntptr(intptr_t value) {
701 ASSERT(Smi::IsValid(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000702 return reinterpret_cast<Smi*>((value << kSmiTagSize) | kSmiTag);
703}
704
705
706Failure::Type Failure::type() const {
707 return static_cast<Type>(value() & kFailureTypeTagMask);
708}
709
710
711bool Failure::IsInternalError() const {
712 return type() == INTERNAL_ERROR;
713}
714
715
716bool Failure::IsOutOfMemoryException() const {
717 return type() == OUT_OF_MEMORY_EXCEPTION;
718}
719
720
721int Failure::requested() const {
722 const int kShiftBits =
723 kFailureTypeTagSize + kSpaceTagSize - kObjectAlignmentBits;
724 STATIC_ASSERT(kShiftBits >= 0);
725 ASSERT(type() == RETRY_AFTER_GC);
726 return value() >> kShiftBits;
727}
728
729
730AllocationSpace Failure::allocation_space() const {
731 ASSERT_EQ(RETRY_AFTER_GC, type());
732 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
733 & kSpaceTagMask);
734}
735
736
737Failure* Failure::InternalError() {
738 return Construct(INTERNAL_ERROR);
739}
740
741
742Failure* Failure::Exception() {
743 return Construct(EXCEPTION);
744}
745
746Failure* Failure::OutOfMemoryException() {
747 return Construct(OUT_OF_MEMORY_EXCEPTION);
748}
749
750
751int Failure::value() const {
ager@chromium.org5ec48922009-05-05 07:25:34 +0000752 return static_cast<int>(reinterpret_cast<intptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000753}
754
755
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000756Failure* Failure::RetryAfterGC(int requested_bytes) {
757 int requested = requested_bytes >> kObjectAlignmentBits;
758 int value = (requested << kSpaceTagSize) | NEW_SPACE;
759 ASSERT(value >> kSpaceTagSize == requested);
760 ASSERT(Smi::IsValid(value));
761 ASSERT(value == ((value << kFailureTypeTagSize) >> kFailureTypeTagSize));
762 ASSERT(Smi::IsValid(value << kFailureTypeTagSize));
763 return Construct(RETRY_AFTER_GC, value);
764}
765
766
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000767Failure* Failure::Construct(Type type, int value) {
768 int info = (value << kFailureTypeTagSize) | type;
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000769 // TODO(X64): Stop using Smi validation for non-smi checks, even if they
770 // happen to be identical at the moment.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000771 ASSERT(Smi::IsValid(info)); // Same validation check as in Smi
ager@chromium.org5ec48922009-05-05 07:25:34 +0000772 return reinterpret_cast<Failure*>(
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000773 (static_cast<intptr_t>(info) << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000774}
775
776
777bool Smi::IsValid(int value) {
778#ifdef DEBUG
779 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
780#endif
781 // To be representable as an tagged small integer, the two
782 // most-significant bits of 'value' must be either 00 or 11 due to
783 // sign-extension. To check this we add 01 to the two
784 // most-significant bits, and check if the most-significant bit is 0
785 //
786 // CAUTION: The original code below:
787 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
788 // may lead to incorrect results according to the C language spec, and
789 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
790 // compiler may produce undefined results in case of signed integer
791 // overflow. The computation must be done w/ unsigned ints.
792 bool result =
793 ((static_cast<unsigned int>(value) + 0x40000000U) & 0x80000000U) == 0;
794 ASSERT(result == in_range);
795 return result;
796}
797
798
ager@chromium.org9085a012009-05-11 19:22:57 +0000799bool Smi::IsIntptrValid(intptr_t value) {
800#ifdef DEBUG
801 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
802#endif
803 // See Smi::IsValid(int) for description.
804 bool result =
805 ((static_cast<uintptr_t>(value) + 0x40000000U) < 0x80000000U);
806 ASSERT(result == in_range);
807 return result;
808}
809
810
kasper.lund7276f142008-07-30 08:49:36 +0000811MapWord MapWord::FromMap(Map* map) {
812 return MapWord(reinterpret_cast<uintptr_t>(map));
813}
814
815
816Map* MapWord::ToMap() {
817 return reinterpret_cast<Map*>(value_);
818}
819
820
821bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000822 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000823}
824
825
826MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000827 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
828 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000829}
830
831
832HeapObject* MapWord::ToForwardingAddress() {
833 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000834 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000835}
836
837
838bool MapWord::IsMarked() {
839 return (value_ & kMarkingMask) == 0;
840}
841
842
843void MapWord::SetMark() {
844 value_ &= ~kMarkingMask;
845}
846
847
848void MapWord::ClearMark() {
849 value_ |= kMarkingMask;
850}
851
852
853bool MapWord::IsOverflowed() {
854 return (value_ & kOverflowMask) != 0;
855}
856
857
858void MapWord::SetOverflow() {
859 value_ |= kOverflowMask;
860}
861
862
863void MapWord::ClearOverflow() {
864 value_ &= ~kOverflowMask;
865}
866
867
868MapWord MapWord::EncodeAddress(Address map_address, int offset) {
869 // Offset is the distance in live bytes from the first live object in the
870 // same page. The offset between two objects in the same page should not
871 // exceed the object area size of a page.
872 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
873
874 int compact_offset = offset >> kObjectAlignmentBits;
875 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
876
877 Page* map_page = Page::FromAddress(map_address);
878 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
879
880 int map_page_offset =
881 map_page->Offset(map_address) >> kObjectAlignmentBits;
882
883 uintptr_t encoding =
884 (compact_offset << kForwardingOffsetShift) |
885 (map_page_offset << kMapPageOffsetShift) |
886 (map_page->mc_page_index << kMapPageIndexShift);
887 return MapWord(encoding);
888}
889
890
891Address MapWord::DecodeMapAddress(MapSpace* map_space) {
892 int map_page_index = (value_ & kMapPageIndexMask) >> kMapPageIndexShift;
893 ASSERT_MAP_PAGE_INDEX(map_page_index);
894
895 int map_page_offset =
896 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift)
897 << kObjectAlignmentBits;
898
899 return (map_space->PageAddress(map_page_index) + map_page_offset);
900}
901
902
903int MapWord::DecodeOffset() {
904 // The offset field is represented in the kForwardingOffsetBits
905 // most-significant bits.
906 int offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
907 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
908 return offset;
909}
910
911
912MapWord MapWord::FromEncodedAddress(Address address) {
913 return MapWord(reinterpret_cast<uintptr_t>(address));
914}
915
916
917Address MapWord::ToEncodedAddress() {
918 return reinterpret_cast<Address>(value_);
919}
920
921
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000922#ifdef DEBUG
923void HeapObject::VerifyObjectField(int offset) {
924 VerifyPointer(READ_FIELD(this, offset));
925}
926#endif
927
928
929Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +0000930 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000931}
932
933
934void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +0000935 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000936}
937
938
kasper.lund7276f142008-07-30 08:49:36 +0000939MapWord HeapObject::map_word() {
940 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
941}
942
943
944void HeapObject::set_map_word(MapWord map_word) {
945 // WRITE_FIELD does not update the remembered set, but there is no need
946 // here.
947 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
948}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000949
950
951HeapObject* HeapObject::FromAddress(Address address) {
952 ASSERT_TAG_ALIGNED(address);
953 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
954}
955
956
957Address HeapObject::address() {
958 return reinterpret_cast<Address>(this) - kHeapObjectTag;
959}
960
961
962int HeapObject::Size() {
963 return SizeFromMap(map());
964}
965
966
967void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
968 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
969 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
970}
971
972
973void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
974 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
975}
976
977
kasper.lund7276f142008-07-30 08:49:36 +0000978bool HeapObject::IsMarked() {
979 return map_word().IsMarked();
980}
981
982
983void HeapObject::SetMark() {
984 ASSERT(!IsMarked());
985 MapWord first_word = map_word();
986 first_word.SetMark();
987 set_map_word(first_word);
988}
989
990
991void HeapObject::ClearMark() {
992 ASSERT(IsMarked());
993 MapWord first_word = map_word();
994 first_word.ClearMark();
995 set_map_word(first_word);
996}
997
998
999bool HeapObject::IsOverflowed() {
1000 return map_word().IsOverflowed();
1001}
1002
1003
1004void HeapObject::SetOverflow() {
1005 MapWord first_word = map_word();
1006 first_word.SetOverflow();
1007 set_map_word(first_word);
1008}
1009
1010
1011void HeapObject::ClearOverflow() {
1012 ASSERT(IsOverflowed());
1013 MapWord first_word = map_word();
1014 first_word.ClearOverflow();
1015 set_map_word(first_word);
1016}
1017
1018
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001019double HeapNumber::value() {
1020 return READ_DOUBLE_FIELD(this, kValueOffset);
1021}
1022
1023
1024void HeapNumber::set_value(double value) {
1025 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1026}
1027
1028
1029ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001030ACCESSORS(JSObject, elements, FixedArray, kElementsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001031
1032
1033void JSObject::initialize_properties() {
1034 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1035 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1036}
1037
1038
1039void JSObject::initialize_elements() {
1040 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1041 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1042}
1043
1044
1045ACCESSORS(Oddball, to_string, String, kToStringOffset)
1046ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1047
1048
1049int JSObject::GetHeaderSize() {
1050 switch (map()->instance_type()) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001051 case JS_GLOBAL_PROXY_TYPE:
1052 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001053 case JS_GLOBAL_OBJECT_TYPE:
1054 return JSGlobalObject::kSize;
1055 case JS_BUILTINS_OBJECT_TYPE:
1056 return JSBuiltinsObject::kSize;
1057 case JS_FUNCTION_TYPE:
1058 return JSFunction::kSize;
1059 case JS_VALUE_TYPE:
1060 return JSValue::kSize;
1061 case JS_ARRAY_TYPE:
1062 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001063 case JS_REGEXP_TYPE:
1064 return JSValue::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001065 case JS_OBJECT_TYPE:
ager@chromium.org32912102009-01-16 10:38:43 +00001066 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001067 return JSObject::kHeaderSize;
1068 default:
1069 UNREACHABLE();
1070 return 0;
1071 }
1072}
1073
1074
1075int JSObject::GetInternalFieldCount() {
1076 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001077 // Make sure to adjust for the number of in-object properties. These
1078 // properties do contribute to the size, but are not internal fields.
1079 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1080 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001081}
1082
1083
1084Object* JSObject::GetInternalField(int index) {
1085 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001086 // Internal objects do follow immediately after the header, whereas in-object
1087 // properties are at the end of the object. Therefore there is no need
1088 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001089 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1090}
1091
1092
1093void JSObject::SetInternalField(int index, Object* value) {
1094 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001095 // Internal objects do follow immediately after the header, whereas in-object
1096 // properties are at the end of the object. Therefore there is no need
1097 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001098 int offset = GetHeaderSize() + (kPointerSize * index);
1099 WRITE_FIELD(this, offset, value);
1100 WRITE_BARRIER(this, offset);
1101}
1102
1103
ager@chromium.org7c537e22008-10-16 08:43:32 +00001104// Access fast-case object properties at index. The use of these routines
1105// is needed to correctly distinguish between properties stored in-object and
1106// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001107Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001108 // Adjust for the number of properties stored in the object.
1109 index -= map()->inobject_properties();
1110 if (index < 0) {
1111 int offset = map()->instance_size() + (index * kPointerSize);
1112 return READ_FIELD(this, offset);
1113 } else {
1114 ASSERT(index < properties()->length());
1115 return properties()->get(index);
1116 }
1117}
1118
1119
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001120Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001121 // Adjust for the number of properties stored in the object.
1122 index -= map()->inobject_properties();
1123 if (index < 0) {
1124 int offset = map()->instance_size() + (index * kPointerSize);
1125 WRITE_FIELD(this, offset, value);
1126 WRITE_BARRIER(this, offset);
1127 } else {
1128 ASSERT(index < properties()->length());
1129 properties()->set(index, value);
1130 }
1131 return value;
1132}
1133
1134
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001135Object* JSObject::InObjectPropertyAt(int index) {
1136 // Adjust for the number of properties stored in the object.
1137 index -= map()->inobject_properties();
1138 ASSERT(index < 0);
1139 int offset = map()->instance_size() + (index * kPointerSize);
1140 return READ_FIELD(this, offset);
1141}
1142
1143
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001144Object* JSObject::InObjectPropertyAtPut(int index,
1145 Object* value,
1146 WriteBarrierMode mode) {
1147 // Adjust for the number of properties stored in the object.
1148 index -= map()->inobject_properties();
1149 ASSERT(index < 0);
1150 int offset = map()->instance_size() + (index * kPointerSize);
1151 WRITE_FIELD(this, offset, value);
1152 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1153 return value;
1154}
1155
1156
1157
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001158void JSObject::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001159 Object* value = Heap::undefined_value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001160 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001161 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001162 }
1163}
1164
1165
1166void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001167 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001168 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001169 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001170 }
1171}
1172
1173
1174bool JSObject::HasFastProperties() {
1175 return !properties()->IsDictionary();
1176}
1177
1178
1179bool Array::IndexFromObject(Object* object, uint32_t* index) {
1180 if (object->IsSmi()) {
1181 int value = Smi::cast(object)->value();
1182 if (value < 0) return false;
1183 *index = value;
1184 return true;
1185 }
1186 if (object->IsHeapNumber()) {
1187 double value = HeapNumber::cast(object)->value();
1188 uint32_t uint_value = static_cast<uint32_t>(value);
1189 if (value == static_cast<double>(uint_value)) {
1190 *index = uint_value;
1191 return true;
1192 }
1193 }
1194 return false;
1195}
1196
1197
1198bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1199 if (!this->IsJSValue()) return false;
1200
1201 JSValue* js_value = JSValue::cast(this);
1202 if (!js_value->value()->IsString()) return false;
1203
1204 String* str = String::cast(js_value->value());
1205 if (index >= (uint32_t)str->length()) return false;
1206
1207 return true;
1208}
1209
1210
1211Object* FixedArray::get(int index) {
1212 ASSERT(index >= 0 && index < this->length());
1213 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1214}
1215
1216
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001217void FixedArray::set(int index, Smi* value) {
1218 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1219 int offset = kHeaderSize + index * kPointerSize;
1220 WRITE_FIELD(this, offset, value);
1221}
1222
1223
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001224void FixedArray::set(int index, Object* value) {
1225 ASSERT(index >= 0 && index < this->length());
1226 int offset = kHeaderSize + index * kPointerSize;
1227 WRITE_FIELD(this, offset, value);
1228 WRITE_BARRIER(this, offset);
1229}
1230
1231
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001232WriteBarrierMode HeapObject::GetWriteBarrierMode() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001233 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1234 return UPDATE_WRITE_BARRIER;
1235}
1236
1237
1238void FixedArray::set(int index,
1239 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001240 WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001241 ASSERT(index >= 0 && index < this->length());
1242 int offset = kHeaderSize + index * kPointerSize;
1243 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001244 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001245}
1246
1247
1248void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
1249 ASSERT(index >= 0 && index < array->length());
1250 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1251}
1252
1253
1254void FixedArray::set_undefined(int index) {
1255 ASSERT(index >= 0 && index < this->length());
1256 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1257 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1258 Heap::undefined_value());
1259}
1260
1261
ager@chromium.org236ad962008-09-25 09:45:57 +00001262void FixedArray::set_null(int index) {
1263 ASSERT(index >= 0 && index < this->length());
1264 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1265 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1266}
1267
1268
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001269void FixedArray::set_the_hole(int index) {
1270 ASSERT(index >= 0 && index < this->length());
1271 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1272 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1273}
1274
1275
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001276bool DescriptorArray::IsEmpty() {
1277 ASSERT(this == Heap::empty_descriptor_array() ||
1278 this->length() > 2);
1279 return this == Heap::empty_descriptor_array();
1280}
1281
1282
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001283void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1284 Object* tmp = array->get(first);
1285 fast_set(array, first, array->get(second));
1286 fast_set(array, second, tmp);
1287}
1288
1289
1290int DescriptorArray::Search(String* name) {
1291 SLOW_ASSERT(IsSortedNoDuplicates());
1292
1293 // Check for empty descriptor array.
1294 int nof = number_of_descriptors();
1295 if (nof == 0) return kNotFound;
1296
1297 // Fast case: do linear search for small arrays.
1298 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001299 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001300 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001301 }
1302
1303 // Slow case: perform binary search.
1304 return BinarySearch(name, 0, nof - 1);
1305}
1306
1307
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001308String* DescriptorArray::GetKey(int descriptor_number) {
1309 ASSERT(descriptor_number < number_of_descriptors());
1310 return String::cast(get(ToKeyIndex(descriptor_number)));
1311}
1312
1313
1314Object* DescriptorArray::GetValue(int descriptor_number) {
1315 ASSERT(descriptor_number < number_of_descriptors());
1316 return GetContentArray()->get(ToValueIndex(descriptor_number));
1317}
1318
1319
1320Smi* DescriptorArray::GetDetails(int descriptor_number) {
1321 ASSERT(descriptor_number < number_of_descriptors());
1322 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1323}
1324
1325
1326void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1327 desc->Init(GetKey(descriptor_number),
1328 GetValue(descriptor_number),
1329 GetDetails(descriptor_number));
1330}
1331
1332
1333void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1334 // Range check.
1335 ASSERT(descriptor_number < number_of_descriptors());
1336
1337 // Make sure non of the elements in desc are in new space.
1338 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1339 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1340
1341 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1342 FixedArray* content_array = GetContentArray();
1343 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1344 fast_set(content_array, ToDetailsIndex(descriptor_number),
1345 desc->GetDetails().AsSmi());
1346}
1347
1348
1349void DescriptorArray::Swap(int first, int second) {
1350 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1351 FixedArray* content_array = GetContentArray();
1352 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1353 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1354}
1355
1356
1357bool Dictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001358 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001359 if (!max_index_object->IsSmi()) return false;
1360 return 0 !=
1361 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1362}
1363
1364
1365uint32_t Dictionary::max_number_key() {
1366 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001367 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001368 if (!max_index_object->IsSmi()) return 0;
1369 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1370 return value >> kRequiresSlowElementsTagSize;
1371}
1372
1373
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001374void Dictionary::set_requires_slow_elements() {
1375 set(kMaxNumberKeyIndex,
1376 Smi::FromInt(kRequiresSlowElementsMask),
1377 SKIP_WRITE_BARRIER);
1378}
1379
1380
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001381// ------------------------------------
1382// Cast operations
1383
1384
1385CAST_ACCESSOR(FixedArray)
1386CAST_ACCESSOR(DescriptorArray)
1387CAST_ACCESSOR(Dictionary)
1388CAST_ACCESSOR(SymbolTable)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001389CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001390CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001391CAST_ACCESSOR(String)
1392CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001393CAST_ACCESSOR(SeqAsciiString)
1394CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001395CAST_ACCESSOR(ConsString)
1396CAST_ACCESSOR(SlicedString)
1397CAST_ACCESSOR(ExternalString)
1398CAST_ACCESSOR(ExternalAsciiString)
1399CAST_ACCESSOR(ExternalTwoByteString)
1400CAST_ACCESSOR(JSObject)
1401CAST_ACCESSOR(Smi)
1402CAST_ACCESSOR(Failure)
1403CAST_ACCESSOR(HeapObject)
1404CAST_ACCESSOR(HeapNumber)
1405CAST_ACCESSOR(Oddball)
1406CAST_ACCESSOR(SharedFunctionInfo)
1407CAST_ACCESSOR(Map)
1408CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001409CAST_ACCESSOR(GlobalObject)
1410CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001411CAST_ACCESSOR(JSGlobalObject)
1412CAST_ACCESSOR(JSBuiltinsObject)
1413CAST_ACCESSOR(Code)
1414CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001415CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001416CAST_ACCESSOR(Proxy)
1417CAST_ACCESSOR(ByteArray)
1418CAST_ACCESSOR(Struct)
1419
1420
1421#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1422 STRUCT_LIST(MAKE_STRUCT_CAST)
1423#undef MAKE_STRUCT_CAST
1424
1425template <int prefix_size, int elem_size>
1426HashTable<prefix_size, elem_size>* HashTable<prefix_size, elem_size>::cast(
1427 Object* obj) {
1428 ASSERT(obj->IsHashTable());
1429 return reinterpret_cast<HashTable*>(obj);
1430}
1431
1432
1433INT_ACCESSORS(Array, length, kLengthOffset)
1434
1435
1436bool String::Equals(String* other) {
1437 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001438 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1439 return false;
1440 }
1441 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001442}
1443
1444
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001445int String::length() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001446 uint32_t len = READ_INT_FIELD(this, kLengthOffset);
1447
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001448 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift);
1449 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift);
1450 ASSERT(kLongStringTag == 0);
1451
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001452 return len >> (StringShape(this).size_tag() + kLongLengthShift);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001453}
1454
1455
1456void String::set_length(int value) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001457 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift);
1458 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift);
1459 ASSERT(kLongStringTag == 0);
1460
1461 WRITE_INT_FIELD(this,
1462 kLengthOffset,
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001463 value << (StringShape(this).size_tag() + kLongLengthShift));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001464}
1465
1466
ager@chromium.org7c537e22008-10-16 08:43:32 +00001467uint32_t String::length_field() {
1468 return READ_UINT32_FIELD(this, kLengthOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001469}
1470
1471
ager@chromium.org7c537e22008-10-16 08:43:32 +00001472void String::set_length_field(uint32_t value) {
1473 WRITE_UINT32_FIELD(this, kLengthOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001474}
1475
1476
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001477Object* String::TryFlattenIfNotFlat() {
ager@chromium.org236ad962008-09-25 09:45:57 +00001478 // We don't need to flatten strings that are already flat. Since this code
1479 // is inlined, it can be helpful in the flat case to not call out to Flatten.
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001480 if (!IsFlat()) {
1481 return TryFlatten();
ager@chromium.org236ad962008-09-25 09:45:57 +00001482 }
ager@chromium.orgddb913d2009-01-27 10:01:48 +00001483 return this;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001484}
1485
1486
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001487uint16_t String::Get(int index) {
1488 ASSERT(index >= 0 && index < length());
1489 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001490 case kSeqStringTag | kAsciiStringTag:
1491 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1492 case kSeqStringTag | kTwoByteStringTag:
1493 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1494 case kConsStringTag | kAsciiStringTag:
1495 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001496 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001497 case kSlicedStringTag | kAsciiStringTag:
1498 case kSlicedStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001499 return SlicedString::cast(this)->SlicedStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001500 case kExternalStringTag | kAsciiStringTag:
1501 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1502 case kExternalStringTag | kTwoByteStringTag:
1503 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001504 default:
1505 break;
1506 }
1507
1508 UNREACHABLE();
1509 return 0;
1510}
1511
1512
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001513void String::Set(int index, uint16_t value) {
1514 ASSERT(index >= 0 && index < length());
1515 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001516
ager@chromium.org5ec48922009-05-05 07:25:34 +00001517 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001518 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1519 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001520}
1521
1522
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001523bool String::IsFlat() {
1524 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001525 case kConsStringTag: {
1526 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001527 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001528 return second->length() == 0;
1529 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001530 case kSlicedStringTag: {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001531 StringRepresentationTag tag =
1532 StringShape(SlicedString::cast(this)->buffer()).representation_tag();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001533 return tag == kSeqStringTag || tag == kExternalStringTag;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001534 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001535 default:
1536 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001537 }
1538}
1539
1540
ager@chromium.org7c537e22008-10-16 08:43:32 +00001541uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001542 ASSERT(index >= 0 && index < length());
1543 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1544}
1545
1546
ager@chromium.org7c537e22008-10-16 08:43:32 +00001547void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001548 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1549 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1550 static_cast<byte>(value));
1551}
1552
1553
ager@chromium.org7c537e22008-10-16 08:43:32 +00001554Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001555 return FIELD_ADDR(this, kHeaderSize);
1556}
1557
1558
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001559char* SeqAsciiString::GetChars() {
1560 return reinterpret_cast<char*>(GetCharsAddress());
1561}
1562
1563
ager@chromium.org7c537e22008-10-16 08:43:32 +00001564Address SeqTwoByteString::GetCharsAddress() {
1565 return FIELD_ADDR(this, kHeaderSize);
1566}
1567
1568
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001569uc16* SeqTwoByteString::GetChars() {
1570 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1571}
1572
1573
ager@chromium.org7c537e22008-10-16 08:43:32 +00001574uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001575 ASSERT(index >= 0 && index < length());
1576 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1577}
1578
1579
ager@chromium.org7c537e22008-10-16 08:43:32 +00001580void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001581 ASSERT(index >= 0 && index < length());
1582 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1583}
1584
1585
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001586int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001587 uint32_t length = READ_INT_FIELD(this, kLengthOffset);
1588
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001589 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift);
1590 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift);
1591 ASSERT(kLongStringTag == 0);
1592
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001593 // Use the map (and not 'this') to compute the size tag, since
1594 // TwoByteStringSize is called during GC when maps are encoded.
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001595 length >>= StringShape(instance_type).size_tag() + kLongLengthShift;
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001596
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001597 return SizeFor(length);
1598}
1599
1600
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001601int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001602 uint32_t length = READ_INT_FIELD(this, kLengthOffset);
1603
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001604 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift);
1605 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift);
1606 ASSERT(kLongStringTag == 0);
1607
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001608 // Use the map (and not 'this') to compute the size tag, since
1609 // AsciiStringSize is called during GC when maps are encoded.
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001610 length >>= StringShape(instance_type).size_tag() + kLongLengthShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001611
1612 return SizeFor(length);
1613}
1614
1615
ager@chromium.org870a0b62008-11-04 11:43:05 +00001616String* ConsString::first() {
1617 return String::cast(READ_FIELD(this, kFirstOffset));
1618}
1619
1620
1621Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001622 return READ_FIELD(this, kFirstOffset);
1623}
1624
1625
ager@chromium.org870a0b62008-11-04 11:43:05 +00001626void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001627 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001628 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001629}
1630
1631
ager@chromium.org870a0b62008-11-04 11:43:05 +00001632String* ConsString::second() {
1633 return String::cast(READ_FIELD(this, kSecondOffset));
1634}
1635
1636
1637Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001638 return READ_FIELD(this, kSecondOffset);
1639}
1640
1641
ager@chromium.org870a0b62008-11-04 11:43:05 +00001642void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001643 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001644 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001645}
1646
1647
ager@chromium.org870a0b62008-11-04 11:43:05 +00001648String* SlicedString::buffer() {
1649 return String::cast(READ_FIELD(this, kBufferOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001650}
1651
1652
ager@chromium.org870a0b62008-11-04 11:43:05 +00001653void SlicedString::set_buffer(String* buffer) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001654 WRITE_FIELD(this, kBufferOffset, buffer);
1655 WRITE_BARRIER(this, kBufferOffset);
1656}
1657
1658
1659int SlicedString::start() {
1660 return READ_INT_FIELD(this, kStartOffset);
1661}
1662
1663
1664void SlicedString::set_start(int start) {
1665 WRITE_INT_FIELD(this, kStartOffset, start);
1666}
1667
1668
1669ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1670 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1671}
1672
1673
1674void ExternalAsciiString::set_resource(
1675 ExternalAsciiString::Resource* resource) {
1676 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1677}
1678
1679
ager@chromium.org6f10e412009-02-13 10:11:16 +00001680Map* ExternalAsciiString::StringMap(int length) {
1681 Map* map;
1682 // Number of characters: determines the map.
1683 if (length <= String::kMaxShortStringSize) {
1684 map = Heap::short_external_ascii_string_map();
1685 } else if (length <= String::kMaxMediumStringSize) {
1686 map = Heap::medium_external_ascii_string_map();
1687 } else {
1688 map = Heap::long_external_ascii_string_map();
1689 }
1690 return map;
1691}
1692
1693
1694Map* ExternalAsciiString::SymbolMap(int length) {
1695 Map* map;
1696 // Number of characters: determines the map.
1697 if (length <= String::kMaxShortStringSize) {
1698 map = Heap::short_external_ascii_symbol_map();
1699 } else if (length <= String::kMaxMediumStringSize) {
1700 map = Heap::medium_external_ascii_symbol_map();
1701 } else {
1702 map = Heap::long_external_ascii_symbol_map();
1703 }
1704 return map;
1705}
1706
1707
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001708ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1709 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1710}
1711
1712
1713void ExternalTwoByteString::set_resource(
1714 ExternalTwoByteString::Resource* resource) {
1715 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1716}
1717
1718
ager@chromium.org6f10e412009-02-13 10:11:16 +00001719Map* ExternalTwoByteString::StringMap(int length) {
1720 Map* map;
1721 // Number of characters: determines the map.
1722 if (length <= String::kMaxShortStringSize) {
1723 map = Heap::short_external_string_map();
1724 } else if (length <= String::kMaxMediumStringSize) {
1725 map = Heap::medium_external_string_map();
1726 } else {
1727 map = Heap::long_external_string_map();
1728 }
1729 return map;
1730}
1731
1732
1733Map* ExternalTwoByteString::SymbolMap(int length) {
1734 Map* map;
1735 // Number of characters: determines the map.
1736 if (length <= String::kMaxShortStringSize) {
1737 map = Heap::short_external_symbol_map();
1738 } else if (length <= String::kMaxMediumStringSize) {
1739 map = Heap::medium_external_symbol_map();
1740 } else {
1741 map = Heap::long_external_symbol_map();
1742 }
1743 return map;
1744}
1745
1746
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001747byte ByteArray::get(int index) {
1748 ASSERT(index >= 0 && index < this->length());
1749 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1750}
1751
1752
1753void ByteArray::set(int index, byte value) {
1754 ASSERT(index >= 0 && index < this->length());
1755 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
1756}
1757
1758
1759int ByteArray::get_int(int index) {
1760 ASSERT(index >= 0 && (index * kIntSize) < this->length());
1761 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
1762}
1763
1764
1765ByteArray* ByteArray::FromDataStartAddress(Address address) {
1766 ASSERT_TAG_ALIGNED(address);
1767 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
1768}
1769
1770
1771Address ByteArray::GetDataStartAddress() {
1772 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
1773}
1774
1775
1776int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001777 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
1778}
1779
1780
1781int Map::inobject_properties() {
1782 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001783}
1784
1785
1786int HeapObject::SizeFromMap(Map* map) {
1787 InstanceType instance_type = map->instance_type();
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001788 // Only inline the most frequent cases.
1789 if (instance_type == JS_OBJECT_TYPE ||
1790 (instance_type & (kIsNotStringMask | kStringRepresentationMask)) ==
1791 (kStringTag | kConsStringTag) ||
1792 instance_type == JS_ARRAY_TYPE) return map->instance_size();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001793 if (instance_type == FIXED_ARRAY_TYPE) {
1794 return reinterpret_cast<FixedArray*>(this)->FixedArraySize();
1795 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001796 if (instance_type == BYTE_ARRAY_TYPE) {
1797 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
1798 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001799 // Otherwise do the general size computation.
1800 return SlowSizeFromMap(map);
1801}
1802
1803
1804void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001805 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00001806 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001807 ASSERT(0 <= value && value < 256);
1808 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
1809}
1810
1811
ager@chromium.org7c537e22008-10-16 08:43:32 +00001812void Map::set_inobject_properties(int value) {
1813 ASSERT(0 <= value && value < 256);
1814 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
1815}
1816
1817
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001818InstanceType Map::instance_type() {
1819 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
1820}
1821
1822
1823void Map::set_instance_type(InstanceType value) {
1824 ASSERT(0 <= value && value < 256);
1825 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
1826}
1827
1828
1829int Map::unused_property_fields() {
1830 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
1831}
1832
1833
1834void Map::set_unused_property_fields(int value) {
1835 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
1836}
1837
1838
1839byte Map::bit_field() {
1840 return READ_BYTE_FIELD(this, kBitFieldOffset);
1841}
1842
1843
1844void Map::set_bit_field(byte value) {
1845 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
1846}
1847
1848
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00001849byte Map::bit_field2() {
1850 return READ_BYTE_FIELD(this, kBitField2Offset);
1851}
1852
1853
1854void Map::set_bit_field2(byte value) {
1855 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
1856}
1857
1858
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001859void Map::set_non_instance_prototype(bool value) {
1860 if (value) {
1861 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
1862 } else {
1863 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
1864 }
1865}
1866
1867
1868bool Map::has_non_instance_prototype() {
1869 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
1870}
1871
1872
ager@chromium.org870a0b62008-11-04 11:43:05 +00001873void Map::set_is_access_check_needed(bool access_check_needed) {
1874 if (access_check_needed) {
1875 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
1876 } else {
1877 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
1878 }
1879}
1880
1881
1882bool Map::is_access_check_needed() {
1883 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
1884}
1885
1886
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001887Code::Flags Code::flags() {
1888 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
1889}
1890
1891
1892void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001893 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001894 // Make sure that all call stubs have an arguments count.
1895 ASSERT(ExtractKindFromFlags(flags) != CALL_IC ||
1896 ExtractArgumentsCountFromFlags(flags) >= 0);
1897 WRITE_INT_FIELD(this, kFlagsOffset, flags);
1898}
1899
1900
1901Code::Kind Code::kind() {
1902 return ExtractKindFromFlags(flags());
1903}
1904
1905
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001906InLoopFlag Code::ic_in_loop() {
1907 return ExtractICInLoopFromFlags(flags());
1908}
1909
1910
kasper.lund7276f142008-07-30 08:49:36 +00001911InlineCacheState Code::ic_state() {
1912 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001913 // Only allow uninitialized or debugger states for non-IC code
1914 // objects. This is used in the debugger to determine whether or not
1915 // a call to code object has been replaced with a debug break call.
1916 ASSERT(is_inline_cache_stub() ||
1917 result == UNINITIALIZED ||
1918 result == DEBUG_BREAK ||
1919 result == DEBUG_PREPARE_STEP_IN);
1920 return result;
1921}
1922
1923
1924PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00001925 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001926 return ExtractTypeFromFlags(flags());
1927}
1928
1929
1930int Code::arguments_count() {
1931 ASSERT(is_call_stub() || kind() == STUB);
1932 return ExtractArgumentsCountFromFlags(flags());
1933}
1934
1935
1936CodeStub::Major Code::major_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001937 ASSERT(kind() == STUB);
kasper.lund7276f142008-07-30 08:49:36 +00001938 return static_cast<CodeStub::Major>(READ_BYTE_FIELD(this,
1939 kStubMajorKeyOffset));
1940}
1941
1942
1943void Code::set_major_key(CodeStub::Major major) {
1944 ASSERT(kind() == STUB);
1945 ASSERT(0 <= major && major < 256);
1946 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001947}
1948
1949
1950bool Code::is_inline_cache_stub() {
1951 Kind kind = this->kind();
1952 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
1953}
1954
1955
1956Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001957 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00001958 InlineCacheState ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001959 PropertyType type,
1960 int argc) {
1961 // Compute the bit mask.
1962 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001963 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00001964 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001965 bits |= type << kFlagsTypeShift;
1966 bits |= argc << kFlagsArgumentsCountShift;
1967 // Cast to flags and validate result before returning it.
1968 Flags result = static_cast<Flags>(bits);
1969 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00001970 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001971 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001972 ASSERT(ExtractTypeFromFlags(result) == type);
1973 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
1974 return result;
1975}
1976
1977
1978Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
1979 PropertyType type,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001980 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001981 int argc) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001982 return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001983}
1984
1985
1986Code::Kind Code::ExtractKindFromFlags(Flags flags) {
1987 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
1988 return static_cast<Kind>(bits);
1989}
1990
1991
kasper.lund7276f142008-07-30 08:49:36 +00001992InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
1993 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001994 return static_cast<InlineCacheState>(bits);
1995}
1996
1997
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001998InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
1999 int bits = (flags & kFlagsICInLoopMask);
2000 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2001}
2002
2003
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002004PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2005 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2006 return static_cast<PropertyType>(bits);
2007}
2008
2009
2010int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2011 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2012}
2013
2014
2015Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2016 int bits = flags & ~kFlagsTypeMask;
2017 return static_cast<Flags>(bits);
2018}
2019
2020
ager@chromium.org8bb60582008-12-11 12:02:20 +00002021Code* Code::GetCodeFromTargetAddress(Address address) {
2022 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2023 // GetCodeFromTargetAddress might be called when marking objects during mark
2024 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2025 // Code::cast. Code::cast does not work when the object's map is
2026 // marked.
2027 Code* result = reinterpret_cast<Code*>(code);
2028 return result;
2029}
2030
2031
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002032Object* Map::prototype() {
2033 return READ_FIELD(this, kPrototypeOffset);
2034}
2035
2036
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002037void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002038 ASSERT(value->IsNull() || value->IsJSObject());
2039 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002040 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002041}
2042
2043
2044ACCESSORS(Map, instance_descriptors, DescriptorArray,
2045 kInstanceDescriptorsOffset)
2046ACCESSORS(Map, code_cache, FixedArray, kCodeCacheOffset)
2047ACCESSORS(Map, constructor, Object, kConstructorOffset)
2048
2049ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2050ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
2051
2052ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2053ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002054ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002055
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002056ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002057
2058ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2059ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2060ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2061ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2062ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
2063
2064ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2065ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2066ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2067
2068ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2069ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2070ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2071ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2072ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2073ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2074
2075ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2076ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2077
2078ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2079ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2080
2081ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2082ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002083ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2084 kPropertyAccessorsOffset)
2085ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2086 kPrototypeTemplateOffset)
2087ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2088ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2089 kNamedPropertyHandlerOffset)
2090ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2091 kIndexedPropertyHandlerOffset)
2092ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2093 kInstanceTemplateOffset)
2094ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2095ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002096ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2097 kInstanceCallHandlerOffset)
2098ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2099 kAccessCheckInfoOffset)
2100ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2101
2102ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002103ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2104 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002105
2106ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2107ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2108
2109ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2110
2111ACCESSORS(Script, source, Object, kSourceOffset)
2112ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002113ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002114ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2115ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002116ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002117ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002118ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2119ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002120ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
iposva@chromium.org245aa852009-02-10 00:49:54 +00002121ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002122ACCESSORS(Script, eval_from_function, Object, kEvalFromFunctionOffset)
2123ACCESSORS(Script, eval_from_instructions_offset, Smi,
2124 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002125
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002126#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002127ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2128ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2129ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2130ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2131
2132ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2133ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2134ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2135ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002136#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002137
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002138ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002139ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
2140ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2141 kInstanceClassNameOffset)
2142ACCESSORS(SharedFunctionInfo, function_data, Object,
2143 kExternalReferenceDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002144ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2145ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002146ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002147
2148BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2149 kHiddenPrototypeBit)
2150BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2151BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2152 kNeedsAccessCheckBit)
2153BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2154 kIsExpressionBit)
2155BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2156 kIsTopLevelBit)
2157
2158INT_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2159INT_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
2160 kFormalParameterCountOffset)
2161INT_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
2162 kExpectedNofPropertiesOffset)
2163INT_ACCESSORS(SharedFunctionInfo, start_position_and_type,
2164 kStartPositionAndTypeOffset)
2165INT_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2166INT_ACCESSORS(SharedFunctionInfo, function_token_position,
2167 kFunctionTokenPositionOffset)
2168
2169
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002170void SharedFunctionInfo::DontAdaptArguments() {
2171 ASSERT(code()->kind() == Code::BUILTIN);
2172 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2173}
2174
2175
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002176int SharedFunctionInfo::start_position() {
2177 return start_position_and_type() >> kStartPositionShift;
2178}
2179
2180
2181void SharedFunctionInfo::set_start_position(int start_position) {
2182 set_start_position_and_type((start_position << kStartPositionShift)
2183 | (start_position_and_type() & ~kStartPositionMask));
2184}
2185
2186
2187Code* SharedFunctionInfo::code() {
2188 return Code::cast(READ_FIELD(this, kCodeOffset));
2189}
2190
2191
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002192void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002193 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002194 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002195}
2196
2197
2198bool SharedFunctionInfo::is_compiled() {
2199 // TODO(1242782): Create a code kind for uncompiled code.
2200 return code()->kind() != Code::STUB;
2201}
2202
2203
2204bool JSFunction::IsBoilerplate() {
2205 return map() == Heap::boilerplate_function_map();
2206}
2207
2208
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002209bool JSObject::IsLoaded() {
2210 return !map()->needs_loading();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002211}
2212
2213
2214Code* JSFunction::code() {
2215 return shared()->code();
2216}
2217
2218
2219void JSFunction::set_code(Code* value) {
2220 shared()->set_code(value);
2221}
2222
2223
2224Context* JSFunction::context() {
2225 return Context::cast(READ_FIELD(this, kContextOffset));
2226}
2227
2228
2229Object* JSFunction::unchecked_context() {
2230 return READ_FIELD(this, kContextOffset);
2231}
2232
2233
2234void JSFunction::set_context(Object* value) {
2235 ASSERT(value == Heap::undefined_value() || value->IsContext());
2236 WRITE_FIELD(this, kContextOffset, value);
2237 WRITE_BARRIER(this, kContextOffset);
2238}
2239
2240ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2241 kPrototypeOrInitialMapOffset)
2242
2243
2244Map* JSFunction::initial_map() {
2245 return Map::cast(prototype_or_initial_map());
2246}
2247
2248
2249void JSFunction::set_initial_map(Map* value) {
2250 set_prototype_or_initial_map(value);
2251}
2252
2253
2254bool JSFunction::has_initial_map() {
2255 return prototype_or_initial_map()->IsMap();
2256}
2257
2258
2259bool JSFunction::has_instance_prototype() {
2260 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2261}
2262
2263
2264bool JSFunction::has_prototype() {
2265 return map()->has_non_instance_prototype() || has_instance_prototype();
2266}
2267
2268
2269Object* JSFunction::instance_prototype() {
2270 ASSERT(has_instance_prototype());
2271 if (has_initial_map()) return initial_map()->prototype();
2272 // When there is no initial map and the prototype is a JSObject, the
2273 // initial map field is used for the prototype field.
2274 return prototype_or_initial_map();
2275}
2276
2277
2278Object* JSFunction::prototype() {
2279 ASSERT(has_prototype());
2280 // If the function's prototype property has been set to a non-JSObject
2281 // value, that value is stored in the constructor field of the map.
2282 if (map()->has_non_instance_prototype()) return map()->constructor();
2283 return instance_prototype();
2284}
2285
2286
2287bool JSFunction::is_compiled() {
2288 return shared()->is_compiled();
2289}
2290
2291
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002292int JSFunction::NumberOfLiterals() {
2293 return literals()->length();
2294}
2295
2296
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002297Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2298 ASSERT(0 <= id && id < kJSBuiltinsCount);
2299 return READ_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize));
2300}
2301
2302
2303void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2304 Object* value) {
2305 ASSERT(0 <= id && id < kJSBuiltinsCount);
2306 WRITE_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize), value);
2307 WRITE_BARRIER(this, kJSBuiltinsOffset + (id * kPointerSize));
2308}
2309
2310
2311Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00002312 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002313}
2314
2315
2316void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00002317 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002318}
2319
2320
2321void Proxy::ProxyIterateBody(ObjectVisitor* visitor) {
2322 visitor->VisitExternalReference(
2323 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
2324}
2325
2326
2327ACCESSORS(JSValue, value, Object, kValueOffset)
2328
2329
2330JSValue* JSValue::cast(Object* obj) {
2331 ASSERT(obj->IsJSValue());
2332 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2333 return reinterpret_cast<JSValue*>(obj);
2334}
2335
2336
2337INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
2338INT_ACCESSORS(Code, relocation_size, kRelocationSizeOffset)
2339INT_ACCESSORS(Code, sinfo_size, kSInfoSizeOffset)
2340
2341
2342Code::ICTargetState Code::ic_flag() {
kasper.lund7276f142008-07-30 08:49:36 +00002343 return static_cast<ICTargetState>(READ_BYTE_FIELD(this, kICFlagOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002344}
2345
2346
2347void Code::set_ic_flag(ICTargetState value) {
kasper.lund7276f142008-07-30 08:49:36 +00002348 WRITE_BYTE_FIELD(this, kICFlagOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002349}
2350
2351
2352byte* Code::instruction_start() {
2353 return FIELD_ADDR(this, kHeaderSize);
2354}
2355
2356
2357int Code::body_size() {
2358 return RoundUp(instruction_size() + relocation_size(), kObjectAlignment);
2359}
2360
2361
2362byte* Code::relocation_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002363 return FIELD_ADDR(this, kHeaderSize + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002364}
2365
2366
2367byte* Code::entry() {
2368 return instruction_start();
2369}
2370
2371
2372bool Code::contains(byte* pc) {
2373 return (instruction_start() <= pc) &&
2374 (pc < instruction_start() + instruction_size());
2375}
2376
2377
2378byte* Code::sinfo_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002379 return FIELD_ADDR(this, kHeaderSize + body_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002380}
2381
2382
2383ACCESSORS(JSArray, length, Object, kLengthOffset)
2384
2385
ager@chromium.org236ad962008-09-25 09:45:57 +00002386ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00002387
2388
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002389JSRegExp::Type JSRegExp::TypeTag() {
2390 Object* data = this->data();
2391 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
2392 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
2393 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00002394}
2395
2396
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002397int JSRegExp::CaptureCount() {
2398 switch (TypeTag()) {
2399 case ATOM:
2400 return 0;
2401 case IRREGEXP:
2402 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
2403 default:
2404 UNREACHABLE();
2405 return -1;
2406 }
2407}
2408
2409
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002410JSRegExp::Flags JSRegExp::GetFlags() {
2411 ASSERT(this->data()->IsFixedArray());
2412 Object* data = this->data();
2413 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
2414 return Flags(smi->value());
2415}
2416
2417
2418String* JSRegExp::Pattern() {
2419 ASSERT(this->data()->IsFixedArray());
2420 Object* data = this->data();
2421 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
2422 return pattern;
2423}
2424
2425
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002426Object* JSRegExp::DataAt(int index) {
2427 ASSERT(TypeTag() != NOT_COMPILED);
2428 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00002429}
2430
2431
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002432void JSRegExp::SetDataAt(int index, Object* value) {
2433 ASSERT(TypeTag() != NOT_COMPILED);
2434 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
2435 FixedArray::cast(data())->set(index, value);
2436}
2437
2438
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002439bool JSObject::HasFastElements() {
2440 return !elements()->IsDictionary();
2441}
2442
2443
2444bool JSObject::HasNamedInterceptor() {
2445 return map()->has_named_interceptor();
2446}
2447
2448
2449bool JSObject::HasIndexedInterceptor() {
2450 return map()->has_indexed_interceptor();
2451}
2452
2453
2454Dictionary* JSObject::property_dictionary() {
2455 ASSERT(!HasFastProperties());
2456 return Dictionary::cast(properties());
2457}
2458
2459
2460Dictionary* JSObject::element_dictionary() {
2461 ASSERT(!HasFastElements());
2462 return Dictionary::cast(elements());
2463}
2464
2465
2466bool String::HasHashCode() {
2467 return (length_field() & kHashComputedMask) != 0;
2468}
2469
2470
2471uint32_t String::Hash() {
2472 // Fast case: has hash code already been computed?
ager@chromium.org7c537e22008-10-16 08:43:32 +00002473 uint32_t field = length_field();
2474 if (field & kHashComputedMask) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002475 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002476 return ComputeAndSetHash();
2477}
2478
2479
ager@chromium.org7c537e22008-10-16 08:43:32 +00002480StringHasher::StringHasher(int length)
2481 : length_(length),
2482 raw_running_hash_(0),
2483 array_index_(0),
2484 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
2485 is_first_char_(true),
2486 is_valid_(true) { }
2487
2488
2489bool StringHasher::has_trivial_hash() {
2490 return length_ > String::kMaxMediumStringSize;
2491}
2492
2493
2494void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002495 // Use the Jenkins one-at-a-time hash function to update the hash
2496 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002497 raw_running_hash_ += c;
2498 raw_running_hash_ += (raw_running_hash_ << 10);
2499 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002500 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002501 if (is_array_index_) {
2502 if (c < '0' || c > '9') {
2503 is_array_index_ = false;
2504 } else {
2505 int d = c - '0';
2506 if (is_first_char_) {
2507 is_first_char_ = false;
2508 if (c == '0' && length_ > 1) {
2509 is_array_index_ = false;
2510 return;
2511 }
2512 }
2513 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
2514 is_array_index_ = false;
2515 } else {
2516 array_index_ = array_index_ * 10 + d;
2517 }
2518 }
2519 }
2520}
2521
2522
2523void StringHasher::AddCharacterNoIndex(uc32 c) {
2524 ASSERT(!is_array_index());
2525 raw_running_hash_ += c;
2526 raw_running_hash_ += (raw_running_hash_ << 10);
2527 raw_running_hash_ ^= (raw_running_hash_ >> 6);
2528}
2529
2530
2531uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002532 // Get the calculated raw hash value and do some more bit ops to distribute
2533 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002534 uint32_t result = raw_running_hash_;
2535 result += (result << 3);
2536 result ^= (result >> 11);
2537 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002538 if (result == 0) {
2539 result = 27;
2540 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002541 return result;
2542}
2543
2544
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002545bool String::AsArrayIndex(uint32_t* index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002546 uint32_t field = length_field();
2547 if ((field & kHashComputedMask) && !(field & kIsArrayIndexMask)) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002548 return SlowAsArrayIndex(index);
2549}
2550
2551
2552Object* JSObject::GetPrototype() {
2553 return JSObject::cast(this)->map()->prototype();
2554}
2555
2556
2557PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
2558 return GetPropertyAttributeWithReceiver(this, key);
2559}
2560
2561
2562bool JSObject::HasElement(uint32_t index) {
2563 return HasElementWithReceiver(this, index);
2564}
2565
2566
ager@chromium.orge2902be2009-06-08 12:21:35 +00002567Smi* JSObject::InterceptorPropertyLookupHint(String* name) {
2568 // TODO(antonm): Do we want to do any shortcuts for global object?
2569 if (HasFastProperties()) {
2570 LookupResult lookup;
2571 LocalLookupRealNamedProperty(name, &lookup);
2572 if (lookup.IsValid()) {
2573 if (lookup.type() == FIELD && lookup.IsCacheable()) {
2574 return Smi::FromInt(lookup.GetFieldIndex());
2575 }
2576 } else {
2577 return Smi::FromInt(kLookupInPrototype);
2578 }
2579 }
2580
2581 return Smi::FromInt(kLookupInHolder);
2582}
2583
2584
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002585bool AccessorInfo::all_can_read() {
2586 return BooleanBit::get(flag(), kAllCanReadBit);
2587}
2588
2589
2590void AccessorInfo::set_all_can_read(bool value) {
2591 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
2592}
2593
2594
2595bool AccessorInfo::all_can_write() {
2596 return BooleanBit::get(flag(), kAllCanWriteBit);
2597}
2598
2599
2600void AccessorInfo::set_all_can_write(bool value) {
2601 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
2602}
2603
2604
ager@chromium.org870a0b62008-11-04 11:43:05 +00002605bool AccessorInfo::prohibits_overwriting() {
2606 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
2607}
2608
2609
2610void AccessorInfo::set_prohibits_overwriting(bool value) {
2611 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
2612}
2613
2614
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002615PropertyAttributes AccessorInfo::property_attributes() {
2616 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
2617}
2618
2619
2620void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
2621 ASSERT(AttributesField::is_valid(attributes));
2622 int rest_value = flag()->value() & ~AttributesField::mask();
2623 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
2624}
2625
2626void Dictionary::SetEntry(int entry,
2627 Object* key,
2628 Object* value,
2629 PropertyDetails details) {
2630 ASSERT(!key->IsString() || details.index() > 0);
2631 int index = EntryToIndex(entry);
2632 WriteBarrierMode mode = GetWriteBarrierMode();
2633 set(index, key, mode);
2634 set(index+1, value, mode);
2635 fast_set(this, index+2, details.AsSmi());
2636}
2637
2638
2639void Map::ClearCodeCache() {
2640 // No write barrier is needed since empty_fixed_array is not in new space.
2641 // Please note this function is used during marking:
2642 // - MarkCompactCollector::MarkUnmarkedObject
2643 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
2644 WRITE_FIELD(this, kCodeCacheOffset, Heap::empty_fixed_array());
2645}
2646
2647
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002648void JSArray::EnsureSize(int required_size) {
2649 ASSERT(HasFastElements());
2650 if (elements()->length() >= required_size) return;
2651 Expand(required_size);
2652}
2653
2654
ager@chromium.org7c537e22008-10-16 08:43:32 +00002655void JSArray::SetContent(FixedArray* storage) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002656 set_length(Smi::FromInt(storage->length()), SKIP_WRITE_BARRIER);
ager@chromium.org7c537e22008-10-16 08:43:32 +00002657 set_elements(storage);
2658}
2659
2660
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002661Object* FixedArray::Copy() {
2662 if (length() == 0) return this;
2663 return Heap::CopyFixedArray(this);
2664}
2665
2666
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002667#undef CAST_ACCESSOR
2668#undef INT_ACCESSORS
2669#undef SMI_ACCESSORS
2670#undef ACCESSORS
2671#undef FIELD_ADDR
2672#undef READ_FIELD
2673#undef WRITE_FIELD
2674#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002675#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002676#undef READ_MEMADDR_FIELD
2677#undef WRITE_MEMADDR_FIELD
2678#undef READ_DOUBLE_FIELD
2679#undef WRITE_DOUBLE_FIELD
2680#undef READ_INT_FIELD
2681#undef WRITE_INT_FIELD
2682#undef READ_SHORT_FIELD
2683#undef WRITE_SHORT_FIELD
2684#undef READ_BYTE_FIELD
2685#undef WRITE_BYTE_FIELD
2686
2687
2688} } // namespace v8::internal
2689
2690#endif // V8_OBJECTS_INL_H_